Django Send Form By Authenticated User - django

i stuck when trying to send data or save data with django form by user it self (logged).
When i test why form "From" user must be selectable not automatic selected by user it self.
class ValidationCreate(forms.ModelForm):
class Meta:
model = About
fields = '__all__'
def upload(request):
upload = ValidationCreate()
if request.method == 'POST':
upload = ValidationCreate(request.POST, request.FILES)
if upload.is_valid():
upload.save()
return redirect('validation')
else:
return HttpResponse("""your form is wrong, reload on reload""")
else:
return render(request, 'upload_form.html', {'about_form': upload})
sample

this way you can assign the request.user
if upload.is_valid():
instance = upload.save(commit=False)
instance.profile = Profile.objects.get(user=request.user) # you can change the user if field name is different
instance.save()
return redirect('validation')
else:
in forms
fields = ['field_1', 'field_2',] # except user field

Related

Django - uploading image to database raises IntegrityError

I'm trying to allow users to upload an image. When users are first created, they are given a unique ID / primary key. When users upload an image, I want to save that image in a folder depending on what the users unique ID is. For example, if the users unique ID is 1, I want to save it in
1/uploadedPhotos/imageName
This is my model:
def get_file_path(instance, filename):
return os.path.join('%s/uploadedPhotos' % instance.user_id, filename)
class UserImages(models.Model):
user = models.ForeignKey(User)
photo = models.ImageField(upload_to=get_file_path)
and this is my form:
class UploadImageForm(forms.ModelForm):
class Meta:
model = UserImages
fields = ['photo']
and this is my view:
def uploadImageView(request):
if request.method == 'POST':
form = UploadImageForm(request.POST, request.FILES)
if form.is_valid():
# file is saved
form.save()
return redirect('/')
else:
form = UploadImageForm()
return render(request, 'uploadImagePage.html', {'uploadImageForm': form})
The URL which calls the uploadImageView view is /uploadImage/. when I go to that URL and upload an image using the uploadImageForm, it gives an error saying:
IntegrityError at /uploadImage/
null value in column "user_id" violates not-null constraint
DETAIL: Failing row contains (1, null, None/uploadedPhotos/imageName.png).
and the traceback leads back to the
form.save()
line in my uploadImageView. What am I doing wrong to cause this error?
Your UserImages model requires user but your form UploadImageForm is asking only asking for photo. You need to set user, try something like this:
def uploadImageView(request):
if request.method == 'POST':
form = UploadImageForm(request.POST, request.FILES)
if form.is_valid():
# file is saved
instance = form.save(commit=False)
instance.user = request.user
instance.save()
return redirect('/')
else:
form = UploadImageForm()
return render(request, 'uploadImagePage.html', {'uploadImageForm': form})
obj = form.save(commit=False)
obj.user = request.user
obj.save()
You must extract user from request.user and add it to form data.

django forms - how to filter number of available options in a form

I'm trying to limit number of "categories" that user have available when entering new "feed" only to categories that he owns and he created. The way it works now is that user can add "feed" to other users' "categories" as this is what the form displays. How can I fix it ?
thanks!
-M
models.py
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=50)
user = models.ForeignKey(User)
class Feed(models.Model):
url = models.URLField()
name = models.CharField(max_length=50)
created = models.DateTimeField(auto_now_add=True)
description = models.TextField(blank=True)
category = models.ForeignKey(Category)
user = models.ForeignKey(User)
forms.py
class FeedForm(forms.ModelForm):
class Meta:
model = Feed
exclude = ['user']
views.py
def addfeed(request, user):
user = request.user
page_title = "Add feed"
instance = Category.objects.filter(user=request.user)
if request.method == 'POST':
form = FeedForm(request.POST, instance=instance)
if form.is_valid():
feed = form.save(commit=False)
feed.user = request.user
feed.save()
return HttpResponseRedirect("/user/" + user.username + "/manage")
else:
form = FeedForm()
return render(request, "form_manage.html", {
'page_title': page_title,
'form': form,
})
Set the queryset attribute of the field somewhere. Because it depends on your user, it's something you have to set during or after instantiating the form. For instance, here's how to do it in the view:
def addfeed(request, user):
user = request.user # why does this view take user as an arg and then reassign?
page_title = "Add feed"
categories = Category.objects.filter(user=request.user)
if request.method == 'POST':
form = FeedForm(request.POST)
form.fields['category'].queryset = categories
if form.is_valid():
feed = form.save(commit=False)
feed.user = request.user
feed.save()
return HttpResponseRedirect("/user/" + user.username + "/manage")
else:
form = FeedForm()
form.fields['category'].queryset = categories
return render(request, "form_manage.html", {
'page_title': page_title,
'form': form,})
I removed the instance argument to your POST case's form construction because that's meant for passing in an existing Feed instance, not a categories queryset.
You could also do this in the form's __init__ if you pass in the correct categories queryset.
I use javascript to do this. For example, you could pass a list of the relevant categories as extra context in your view then use javascript in your template to empty the pre-populated option field in the form and replace it with your extra context.

How to save current login user? user_id may not be NULL

I have this error:
appname_mymodel.user_id may not be NULL
def form_view(request):
user = request.user
f_form = FForm(request.POST or None, request.FILES or None)
if request.method == "POST":
if f_form.is_valid():
f_form.user = user
f_form.save()
return HttpResponseRedirect('/thanks/')
return render_to_response('upload.html', {'f_form': f_form}, context_instance=RequestContext(request))
forms.py:
class FForm(ModelForm):
class Meta:
model = MyModel
exclude =['user']
How to save current login user?
The form doesn't have a user attribute so it is useless to assign to it. What you should do instead is:
if f_form.is_valid():
my_model = f_form.save(commit=False)
my_model.user = user
my_model.save()
This way the form will construct a MyModel instance, but will not attempt to save it to the database. Then you can fill the user field and save it.
You can also provide the necessary data as an instance argument:
f_form = FForm(request.POST or None, request.FILES or None, \
instance = MyModel(user=user))
if request.method == "POST":
if f_form.is_valid():
f_form.save()
return HttpResponseRedirect('/thanks/')

Django Form problems with UserProfile

I'd like to create a "update user's profile" page to let users modify their profiles, so I come up with the following models:
class Profile(models.Model):
user = models.OneToOneField(User)
nick_name = models.CharField(blank=True,max_length=100)
school = models.CharField(blank=True,max_length=100)
motto = models.CharField(blank=True,max_length=100)
class ProfileForm(ModelForm):
class Meta:
model = Profile
And my view is designed as:
#login_required
def update_profile_view(request):
if request.method == 'POST':
user = request.user
try:
profile = user.get_profile()
except Exception:
profile = Profile.objects.create(user=user)
form = ProfileForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
profile.nick_name = cd['nick_name']
profile.school = cd['school']
profile.motto = cd['motto']
profile.save()
return HttpResponseRedirect('/main_page/')
else:
form = ProfileForm()
return render(request, 'update_profile.html', {'form':form})
The relationship between an user and a profile is apparently 1to1, and with request I can determine the current user. So the form's user field needn't to be filled. Unfortunately, this couldn't pass "the form.is_valid()" test. And it seems hard to modify a form before "is_valid" invoked. For simplicity, I don't want to create my own Form Class, neither do I want to write customized form validation. Is there any other way to solve the problem?
Your view can be greatly simplified:
#login_required
def update_profile_view(request):
try:
profile = Profile.objects.get(user=request.user)
except Profile.DoesNotExist:
profile = None
form = ProfileForm(request.POST or None, instance=profile)
if request.method == 'POST':
if form.is_valid():
form.save()
return HttpResponseRedirect('/main_page/')
return render(request, 'update_profile.html', {'form':form})
There's no need to manually assign the fields like you're doing. Django ORM knows how to do an insert versus an update automatically. So if you simply pass the ProfileForm an instance of a Profile, it knows to do an update. If there's no instance of a profile, it's going to do an insert.
Now, if you want to make the assignment of the user transparent in the UI, you'll need to exclude the user field from the form and assign it yourself. There are a couple of different ways to do that.
I would also recommend leveraging reverse in your redirect so you don't have a hard-coded path.
You have basicly two choices:
1 Modification of ProfileForm:
class ProfileForm(ModelForm):
class Meta:
model = Profileclass
exclude = ('user',)
2 Change this lines as follows:
form = ProfileForm(request.POST, instance=profile)
if form.is_valid():
updated_profile = form.save()
You can either set the user field's value to not required in the init method (self.fields['user'].required = False) of the form or set the user not editable in the model (editable=False).
In your view method, call profile = form.save(commit=False), then do profile.user = your_user and profile.save()
You don't have to apply the cleaned data manually to the profile since the ModelForm does this.

Django: associating a user with model instance

Let's say that I have a model that handles recipes, and I want to allow users to input their own recipes via a form. I then want to associate that recipe entry with the user ID of the user who inputted it. My guess is that my model would look something like this:
class Recipe(models.Model):
name = models.CharField(max_length=100)
body = models.TextField()
creator = models.ManyToManyField(User)
def __unicode__(self):
return self.creator
Is that correct? And if I created a model form, it would look something like this:
class RecipeForm(ModelForm):
class Meta:
model = Recipe
But how would I go about automatically passing the user information to the Recipe model upon submission? Would this take place in my view?
My current view is like this:
def recipe(request):
if request.method == 'POST':
form = RecipeForm(request.POST) #if POST method, bound form to POST data
if form.is_valid():
form.save()
else:
form = RecipeForm() #unbound form.
recipe_list = Recipe.objects.all()
return render_to_response('forms/recipes.html',
{'form': form, 'recipe_list': recipe_list},
context_instance = RequestContext(request))
How would I set the user to the model before saving it?
Yes, your view would need to set the user on the recipe model before saving it.
Edit:
You should accept Ignacio's answer, since he added it in the comment.
Here is how you would add your user:
from django.shortcuts import render
def recipe(request):
if request.method == 'POST':
form = RecipeForm(request.POST) #if POST method, bound form to POST data
if form.is_valid():
obj = form.save(commit=False) # don't save to DB
obj.creator = request.user # adds the user
obj.save()
else:
form = RecipeForm() #unbound form.
recipe_list = Recipe.objects.all()
return render(request,'forms/recipes.html',
{'form': form, 'recipe_list': recipe_list})