Updating a user/profile model object

1,220 views
Skip to first unread message

JonRob

unread,
Jan 27, 2010, 2:42:07 PM1/27/10
to Django users
Hi,

I'm just starting out learning Django, trying to cut my teeth by
working on a simple website that involves a user profile.

I've created a ModelForm of the profile model, that instances the
profile of the logged in user, which I then want the user to be able
to update so that they can update their profile information. When I
hit the update button, however, I get a validation error pointing at
the ForeignKey field which links the profile to the User model.

I think the problem is that form.save() is trying to insert another
record, rather than update the current, probably related to the
primary key being automatically incremented, but I can't figure out
how to fix it. I was hoping somebody here might be able to point me in
the right direction.

Relevant code snippets are below:

--------------------

#models.py

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

class Organisation(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField(max_length=50)
organisation_name = models.CharField(max_length=50)
club_name = models.CharField(max_length=50)
paypal_address = models.EmailField(max_length=50)
phone_number = models.IntegerField()
coach_company = models.CharField(max_length=50)
user = models.ForeignKey(User, unique=True, primary_key=True)

class OrganisationForm(ModelForm):
class Meta:
model = Organisation

#views.py

from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.models import User
from django.template import Context, loader
from FanTran.organisations.models import OrganisationForm

def profile(request):
if request.user.is_authenticated():

organisation = request.user.get_profile()
profile_form = OrganisationForm(instance=organisation)

profile = request.user.get_profile()
t = loader.get_template('organisations/profile.html')
c = Context ({
'profile_form':profile_form,
'profile':profile,
})
return HttpResponse(t.render(c))
else:
return HttpResponse('Error: Not a valid user')

def profile_update(request):
if request.user.is_authenticated():
if request.method == 'POST':
form = OrganisationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('accounts/profile/')
else:
return HttpResponse(form.errors)
else:
return HttpResponseRedirect('/login/')

---------------

Thanks in advance,

Jon

Daniel Roseman

unread,
Jan 27, 2010, 4:36:49 PM1/27/10
to Django users

You're posting your update to a different view from the one that
initially displays the form. The usual way to do this is to have the
form post back to the same view, but have an 'if request.POST' to
branch the execution. The main forms documentation explains the
standard flow.

The main problem, though, is that you're not passing the instance into
the form when you instantiate on post, so as you say the form creates
a new instance. You just need to get the profile (that's where it
makes sense to use the same view for display and post) and pass it in
just as you do in the other view:
form = OrganisationForm(request.POST, instance=organisation)

Also, no doubt you recognise this, but if the form produces errors,
your view will display them, but not re-display the form to allow the
user to correct and resubmit. Once again, that's where using the same
view for display and post makes sense.
--
DR.

Jonathan Roberts

unread,
Jan 28, 2010, 4:23:38 PM1/28/10
to django...@googlegroups.com
> You're posting your update to a different view from the one that
> initially displays the form. The usual way to do this is to have the
> form post back to the same view, but have an 'if request.POST' to
> branch the execution. The main forms documentation explains the
> standard flow.

Ah I did see that, but I was planning on having a number of forms on
the same page and wasn't sure it would work if I left it as is?


>
> The main problem, though, is that you're not passing the instance into
> the form when you instantiate on post, so as you say the form creates
> a new instance. You just need to get the profile (that's where it
> makes sense to use the same view for display and post) and pass it in
> just as you do in the other view:
>    form = OrganisationForm(request.POST, instance=organisation)

Great, that fixed it in my separate view, so thanks for the tip! I'll
give it some more thought as to whether or not to go back to having it
in a single view or not.

Again, many thanks :)

Jon

Reply all
Reply to author
Forward
0 new messages