jeffci
jeffci

Reputation: 2622

Django forms and set initial value to logged in user?

I have a form like so:

from django import forms
from django.contrib.auth.models import User

from django_countries.countries import COUNTRIES

from statuses.models import Status

class StatusForm(forms.Form):
    country = forms.ChoiceField(choices=COUNTRIES)
    mood = forms.IntegerField()
    sleep_quality = forms.IntegerField()

This form is only displayed to the users who are logged in, how can I set request.user so that when the user submits this form, I can associate the form entry to them? My model looks like the following with the the user FK:

from django.db import models
from django.contrib.auth.models import User

from django_countries import CountryField

class Status(models.Model):
    user = models.ForeignKey(User)
    country = CountryField()
    mood = models.SmallIntegerField(default=4)
    sleep_quality = models.SmallIntegerField(default=4)

Here is my view for this form as well:

@login_required
def index(request, template_name="status/index.html"):
    if request.method == 'POST':
        postdata = request.POST
        form = StatusForm(postdata)
        if form.is_valid():
            messages.success(request, 'Something happened, good!')
            return redirect(urlresolvers.reverse('profile'))
    else:
        form = StatusForm()
    context = RequestContext(request, { 'form': form })
    return render_to_response(template_name, context)

I thought maybe I should create a hiddenfield and store request.user in there but that does not seem safe as it can easily be edited with firebug and such. Any suggestions as to how I can store request.user for this form?

Thanks!

Upvotes: 0

Views: 2915

Answers (1)

Timmy O'Mahony
Timmy O'Mahony

Reputation: 53999

The current user will be present in the request as request.user so you don't need to include it in the form. Instead why not leverage ModelForms as they will deal with linking your object to your form.

class StatusForm(forms.ModelForm):
    country = forms.ChoiceField(choices=COUNTRIES)
    # The other fields are automatically included, we just overwrite country

    class Meta:
        model = Status
        exclude = ("user")

Then in your view:

...
form = StatusForm(request.POST):
    if form.is_valid():
        # Because your model requires that user is present, we validate the form and 
        # save it without commiting, manually assigning the user to the object and resaving
        obj = form.save(commit=False)
        obj.user = request.user
        obj.save()
        messages.success(request, 'Something happened, good!')
        return redirect(urlresolvers.reverse('profile'))
     ...

Upvotes: 6

Related Questions