Question

This is my forms.py snippet

class ContactForm(forms.ModelForm):
    class Meta:
        model = Contact
        exclude = ('user',)

This is my views.py snippet

def contact(request, template_name):
    if request.method == "POST":
        form = ContactForm(request.POST)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.user = request.user
            obj.save()
            return HttpResponseRedirect('/newuser/step2/')
    else:
        if (Contact.objects.filter(user=request.user)):
            contact_obj = Contact.objects.get(user_id=request.user.id)
            form = ContactForm(instance = contact_obj)
        else:
            form = ContactForm()

    return render_to_response(template_name, RequestContext(request, {'form' : form}))

When i fill the data for the first time for a registered user, data successfully goes into the table. When i visit the form again, data from database is loaded, but when re-submit, below errors come

Exception Type: IntegrityError
Exception Value:    (1062, "Duplicate entry '3' for key 'user_id'")
Exception Location: /usr/lib/python2.7/dist-packages/MySQLdb/connections.py in defaulterrorhandler, line 36

My contact table has the automatically generated 'id' field as primary key, while 'user_id' is the foreign key field. '3' is the 'user_id' for logged in user.

I am trying to do a very simple thing, store some data for user in a table and link it. Is there a better way to do it? What is it that I am doing wrong here?

Was it helpful?

Solution

Since you are editing, you need to get the form object using the object instance. In your case, it tries to create a new object, but since this pk already exists, it is throwing the integrity error.

form = ContactForm(request.POST, instance=contact_obj)

Move the creation of contact_obj up to the beginning of the view method

Something like this:

from django.core.exceptions import MultipleObjectsReturned
def contact(request, template_name):
    try:
        contact_obj = Contact.objects.get(user=request.user)
    except: #You might want to handle multiple objects returned case here too..
        contact_obj = None

    form = ContactForm(instance=contact_obj)

    if request.method == "POST":
        form = ContactForm(request.POST, instance=contact_obj)
        if form.is_valid():
            obj = form.save(commit=False)
            obj.user = request.user
            obj.save()
            return HttpResponseRedirect('/newuser/step2/')

    return render_to_response(template_name, RequestContext(request, {'form' : form}))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top