Set user field in a form object created using Mode

2019-08-02 10:17发布

问题:

I have a registration form that when the user enters in valid registration data in it, it logs the user in and redirects the user to another form to enter more data. This new form contains more data about the user and is created using the ModelForm class below:

class UserProfileAddForm(ModelForm):
    class Meta:
        model = UserProfile
        exclude = ('user')

and the UserProfile model looks like:

class UserProfile(models.Model):
    GRADE_YEAR_CHOICES = (
        ('FR', 'Freshman'),
        ('SO', 'Sophomore'),
        ('JR', 'Junior'),
        ('SR', 'Senior'),
        ('GR', 'Graduate')
    )

    school = models.CharField(max_length=64)
    grade_year = models.CharField(max_length=2, choices=GRADE_YEAR_CHOICES)
    gpa = models.DecimalField(decimal_places=2, max_digits=6, blank=True, null=True)
    user = models.ForeignKey(User, unique=True)

Where the user field is a ForeignKey to Django's User object. I am having a hard time setting the user field to the user making the request. Here is what I have tried in my views.py

First attempt:

def more(request):
    if request.method == 'POST':
        form = UserProfileAddForm(request.POST)
        if form.is_valid():
            form.save(commit=False)
            form.user = request.user
            form.save()
            return HttpResponseRedirect('/register/success/')
    else:
        form = UserProfileAddForm()
        variables = RequestContext(request, {
            'form': form

Second attempt:

def more(request):
    if request.method == 'POST':
        form = UserProfileAddForm(request.POST)
        if form.is_valid():
            form.save(commit=False)
            form.user = User.objects.filter(username=request.user)
            form.save()
            return HttpResponseRedirect('/register/success/')
    else:
        form = UserProfileAddForm()
        variables = RequestContext(request, {
            'form': form
        })
        return render_to_response('registration/more.html', variables)

Either way I try it does not seem to save the data to the database. It will however redirect me to the success page as though it did save successfully.

回答1:

form.save() returns an instance of the model being saved. It's there that you need to set the user, then save that instance.

profile = form.save(commit=False)
profile.user = request.user
profile.save()

Note that getting the user from the database based on the value of request.user is pointless, as request.user already is the correct User object.



回答2:

My suggestion is that you make this change in second attempt:

        with_profile = form.save(commit=False)
        with_profile.user = request.user
        form.save()
        ...

Problem is that you are adding user property to form object insteat to form.instance object.

Edited

When I posted first answer I mistaked in user assignement. @Dirk has commented it below and now is fixed. Thanks @Dirk. Problem was that a query set is assigned to with_profile.user insteat a single model.



回答3:

Well, what you need to understand is you get the model instance when you do i.e. in you case

profile = form.save(commit =False)

And when you save the model object it does not saves any Many To Many relationship. Which you need to do after you save the model object. By doing this,

form.save_m2m()

So, just add the last piece of code after you have saved the model object.