ThriceGood
ThriceGood

Reputation: 1703

Django: Updating models, new instance created instead of updated

i am trying to make a simple profile edit form for users on a website. I've followed the standard advice for updating, in the docs it says that Django detects the instances primary key and knows to update instead of insert.

only problem is, i get an insert when i am trying to update. I pre populate a form with a model instance (the instance that im trying to edit) but when i try and save it, i get a new instance. When i add the 'force_update=True' line, i get an error message that tells me that no primary key is detected. Not sure why, because im pre populating the form with a model instance, although, obviously the pk is not a part of the form. is there something im missing?

some code:

the model:

class profile(models.Model):
    user = models.ForeignKey(User)
    first_name = models.CharField(max_length=20, null=True)
    last_name = models.CharField(max_length=20, null=True)
    DOB = models.DateField(null=True)
    age = models.IntegerField(null=True)
    public_email = models.EmailField(null=True)
    county = models.CharField(max_length=20, null=True)
    town = models.CharField(max_length=30, null=True)

the form:

class profileForm(forms.ModelForm):
    class Meta:
        model = profile
        exclude = ['user']

the view:

@login_required()
def edit_profile(request):
    if request.POST:
        proform = profileForm(request.POST)
        if proform.is_valid():
            prof = proform.save(False)
            prof.user = request.user
            prof.save(force_update=True)

        return HttpResponseRedirect('/accounts/view_profile/')
    else:
        c = {}
        if profile.objects.filter(user=request.user).exists():
            prof = profile.objects.get(user=request.user)
            c['proform'] = profileForm(instance=prof)
        else:
            c['proform'] = profileForm()

        return render(request, 'edit_profile.html', c)

any help greatly appreciated!

Upvotes: 0

Views: 1186

Answers (1)

ThriceGood
ThriceGood

Reputation: 1703

i got it, turns out i was trying to just calling save() on the form without specifying the particular instance that the form relates to.

code:

@login_required()
def edit_profile(request):
    c = {}
    if profile.objects.filter(user=request.user).exists():
        profModel = profile.objects.get(user=request.user)
        c['proform'] = profileForm(instance=profModel)
    else:
        c['proform'] = profileForm()

    if request.POST:
        # this line here, added 'instance=profModel' to specify
        # the actual instance i want to save
        proform = profileForm(request.POST, instance=profModel)
        if proform.is_valid():
            prof = proform.save(False)
            prof.user = request.user
            prof.save()

        return HttpResponseRedirect('/accounts/view_profile/')
    else:

        return render(request, 'edit_profile.html', c)

works!

Upvotes: 1

Related Questions