I have two models
class User(auth.models.User,auth.models.PermissionsMixin):
def __str__(self):
return "#{}".format(self.username)
class Profile(models.Model):
user = models.OneToOneField(User,default=None,
null=True,on_delete=models.CASCADE,)
name = models.CharField(max_length=128) #actual creator's name
In the forms.py
class ProfileForm(forms.ModelForm):
class Meta:
exclude = ['user']
# fields = '__all__'
model = models.Profile
In views.py
def TestPage(request):
form = ProfileForm
if request.method == "POST":
form = ProfileForm(request.POST)
if form.is_valid():
form_instance=form.save(commit=False)
form_instance.user = request.user
form_instance.save()
return render(request,'test.html')
else:
print('ERROR FORM INVALID')
return render(request,'accounts/update_profile.html',{'form':form})
I think there is an issue with the line form_instance.user = request.user. I am getting an errorCannot assign ">": "Profile.user" must be a "User" instance. To Profile.user I want save current user. could someone help me with this? Thanks.
Try this
form_instance.user = request.user.pk
If not work then add your models.py
Maybe you can try like this:
form_instance.user = User.objects.get(pk=request.user.pk)
But also make sure that user is logged in before coming to this line(Like using #login_required or LoginRequiredMixin).
Related
my question is about modelforms, models and instances. After doing some troubleshooting I think my problem is that either the user field from UserFile doesn't associate itself to the auth.User or that the modelform doesn't pass the instance of auth.User. The error is at the dynamic pathing - file_destination - when I try self.user it can't find the user :/
# Model
class UserFile(models.Model):
user = models.ForeignKey('auth.User', related_name='user_file', primary_key=True, unique=True)
user_file = models.FileField(upload_to=file_destination, null=True)
def __unicode__(self):
return self.user_file.name
# View
def login_index(request):
template = 'loginIndex.html'
context = Context()
if request.user.is_authenticated():
if request.method == 'POST':
form = UserUpload(request.POST, request.FILES, instance=request.user)
context.update({'form': form})
if form.is_valid() and form.is_multipart():
instance = UserFile(user_file=request.FILES.get('user_file'))
instance.save()
else:
form = UserUpload()
context.update({'form': form})
return render(request, template, context)
else:
return render(request, template, context)
# Form
class UserUpload(ModelForm):
user_file = forms.FileField(required=False, widget=forms.ClearableFileInput, label='Upload')
class Meta:
model = UserFile
fields = ['user_file']
def clean_user_file(self):
check_user_file = self.cleaned_data.get('user_file')
if check_user_file:
if check_user_file.size > 5120000:
raise ValueError('File is too big for upload')
return check_user_file
# The problem arises when I submit the instance, which saves the file from the form to upload_to=file_destination
# In file_destination I get an error on self.user.username saying || DoesNotExist at "" UserFile has no user.
# My self.user is an None object.
def file_destination(self, filename):
filename = name_generator()
url = "%s/%s/%s" % (self.user.username, 'uploads' ,filename)
return url
You need to manually set the user field on your UserFile instance:
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instanve.save()
form.save_m2m() # add this if you add m2m relationships to `UserFile`
Also, it is a good idea to redirect after the form handling succeeds:
from django.shortcuts import redirect
# ...
return redirect("view-name")
I need to make an automatic add in a ManyToMany field. My Class :
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='student')
courses_list = models.ManyToManyField(Course, blank=True)
After saving a new Course I want to add it to course_list of the user :
def newcourse(request):
if not request.user.is_authenticated():
return render_to_response('login.html')
form = CourseForm()
if request.method == 'POST':
form = CourseForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.owner = request.user
obj = form.save()
course_list = request.user.userprofile.courses_list.all()
course_list += form
course_list.save()
return render(request, 'mycourses.html')
return render(request, 'newcourse.html', locals())
But it doesn't works : `unsupported operand type(s) for +=: 'ManyRelatedManager' and 'CourseForm'``
Maybe I need to make an new request ?
If you have an idea.. :D
You need to do the following:
request.user.userprofile.courses_list.add(obj)
See the docs on ManyToMany relationships for more detail:
https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/
Of course, you should probably handle getting the profile in the "proper" way as well:
try:
profile = request.user.get_profile()
profile.courses_list.add(obj)
except UserProfile.DoesNotExist:
messages.error(request, "Couldn't find profile")
Django will just go to the else condition.
here's the code:
models.py
class StakeholderProfile(models.Model):
types = models.ForeignKey(Stakeholder)
name = models.CharField(blank=False, max_length=50)
forms.py
class SPForm(forms.ModelForm):
class Meta:
model = StakeholderProfile
exclude = ('key_contact_person',)
views.py
def profile(request):
stakeholderprofile = StakeholderProfile.objects.all()
if request.method == 'POST':
form = SPForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/profile/')
else:
form = SPForm()
return render_to_response('profile.html',{'form':form,'sp':stakeholderprofile})
I really need your help sir/maam.
You are excluding a field that doesn't exist in StakeHolderProfile.
Also be sure you added method='POST' in your form tag.
I've a modelform and I excluded two fields, the create_date and the created_by fields. Now I get the "Not Null" error when using the save() method because the created_by is empty.
I've tried to add the user id to the form before the save() method like this: form.cleaned_data['created_by'] = 1 and form.cleaned_data['created_by_id'] = 1. But none of this works.
Can someone explain to me how I can 'add' additional stuff to the submitted modelform so that it will save?
class Location(models.Model):
name = models.CharField(max_length = 100)
created_by = models.ForeignKey(User)
create_date = models.DateTimeField(auto_now=True)
class LocationForm(forms.ModelForm):
class Meta:
model = Location
exclude = ('created_by', 'create_date', )
Since you have excluded the fields created_by and create_date in your form, trying to assign them through form.cleaned_data does not make any sense.
Here is what you can do:
If you have a view, you can simply use form.save(commit=False) and then set the value of created_by
def my_view(request):
if request.method == "POST":
form = LocationForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.created_by = request.user
obj.save()
...
...
`
If you are using the Admin, you can override the save_model() method to get the desired result.
class LocationAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.created_by = request.user
obj.save()
Pass a user as a parameter to form constructor, then use it to set created_by field of a model instance:
def add_location(request):
...
form = LocationForm(user=request.user)
...
class LocationForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(forms.ModelForm, self).__init__(*args, **kwargs)
self.instance.created_by = user
The correct solution is to pass an instance of the object with pre-filled fields to the model form's constructor. That way the fields will be populated at validation time. Assigning values after form.save() may result in validation errors if fields are required.
LocationForm(request.POST or None, instance=Location(
created_by=request.user,
create_date=datetime.now(),
))
Notice that instance is an unsaved object, so the id will not be assigned until form saves it.
One way to do this is by using form.save(commit=False) (doc)
That will return an object instance of the model class without committing it to the database.
So, your processing might look something like this:
form = some_form(request.POST)
location = form.save(commit=False)
user = User(pk=1)
location.created_by = user
location.create_date = datetime.now()
location.save()
I'm creating a custom profile page and I need the user to be able to save or update his profile. For some reason I'm getting the following error when I hit the update profile button:
User matching query does not exist.
Below is the code I have for the forms, models and views files:
forms.py
class ProfileForm(forms.Form):
profile_name = forms.CharField( max_length=50)
models.py
class UserProfile(models.Model):
user = models.ForeignKey(User)
profile_name = models.CharField(blank=True, max_length=50)
def __unicode__(self):
return u'%s %s' % (self.user, self.profile_name)
views.py
def edit_profile(request):
if 'edit_button' in request.POST:
form = ProfileForm(request.POST)
f_user = User.objects.get(username=request.user.id)
f_profile_name = form.cleaned_data['profile_name']
p = UserProfile(user=f_user, profile_name=f_profile_name)
p.save()
else:
form = ProfileForm()
return render_to_response('userprofile_template.html', locals(), context_instance=RequestContext(request))
Any idea what am I not doing right? Thank You!
f_user = User.objects.get(username=request.user.id)
Username is presumabely request.user.username
Or, just user User.objects.get(id=request.user.id)
Actually what is my caffienated ass saying? You have your user object right there!
request.user : )