lakshmen
lakshmen

Reputation: 29074

Saving the edited information in Django

I have created a form in my app where I can take details of a suer. Now i am able to edit the form but i am not able to save the data. I would like to save the changed data and move on.

It says: Adult with this User already exists.

My urls.py:

url(r'^home/editform/(?P<userpk>[^/]+)/$', 'lexuseditform', name='lexuseditform'),
url(r'^home/edited/(?P<userpk>[^/]+)/$', 'lexusedited', name='lexusedited')

My views.py:

@login_required                              
def lexuseditform(request,userpk):
    if int(userpk) != request.user.pk:
        return HttpResponseForbidden()
    else:
        adult = Adult(user=request.user)
        if request.method == 'POST': # If the form has been submitted...
            form = AdultForm(request.POST,instance=adult) # A form bound to the POST data
            if form.is_valid(): # All validation rules pass
              form.save()
              redirect_url = reverse('lexusedited')
              return HttpResponseRedirect(redirect_url) # Redirect after POST
        else:
           form = AdultForm(instance=adult) # An unbound form

    return render(request,'lexus/lexuseditform.html', {'form': form})

@login_required                              
def lexusedited(request,userpk):
    return render(request,'lexus/lexusedited.html')

My forms.py:

from models import Adult from django.forms import ModelForm

class AdultForm(ModelForm):
    """
    Edit Profile Information
    """
    class Meta:
        model = Adult
        fields = ('user', 'email','fullname')

My models.py:

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

class Adult(models.Model):
    """
    Adult Information
    """
    user = models.OneToOneField(User)
    fullname = models.CharField(max_length=100)
    email = models.EmailField()

    def __unicode__(self):
        return self.user.username

Not sure where my error is. Need some guidance.. Thanks..

Upvotes: 0

Views: 118

Answers (3)

lakshmen
lakshmen

Reputation: 29074

Correct Version(Refering to Tisho's Answer):

My views.py:

@login_required                              
def lexuseditform(request,userpk):
    if Adult.objects.filter(user=request.user).exists():
        adult = Adult.objects.get(user=request.user) # load existing Adult
    else:
        adult = Adult(user=request.user) # create new Adult
    if request.method == 'POST': # If the form has been submitted...
        form = AdultForm(request.POST,instance=adult) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            form.save()
            redirect_url = reverse('lexusedited')
            return HttpResponseRedirect(redirect_url) # Redirect after POST
    else:
           form = AdultForm(instance=adult) # An unbound form

    return render(request,'lexus/lexuseditform.html', {'form': form})

Upvotes: 0

Tisho
Tisho

Reputation: 8482

Although you haven't shown the Adult model structure, I bet it has something like

class Adult(models.Model):
    user = models.ForeignKey(User, unique=True)

That's why you cannot save new Adult() with the same user(name). So you have to either change the models, or to load existing Adult for the specified user:

if Adult.objects.filter(user=request.user).exists():
    adult = Adult.objects.get(user=request.user) # load existing Adult
else:
    adult = Adult(user=request.user) # create new Adult

But I don't know how your form and models look like.

UPDATE:

or using:

adult, is_created = Adult.objects.get_or_create(user=request.user)

Upvotes: 1

bruno desthuilliers
bruno desthuilliers

Reputation: 77912

A bit of a guess since you didn't post the code for your form and model, but assuming the form is a regular model form, your problem very probably comes from your Adult model having a unique constraint on User (either a OneToOneField or a ForeignKey with unique=True). Since you create a new Adult instance for the form, it violates the unique constraint. Assuming (once again) this constraint is what you want, and your view is supposed to either create a related Adult instance for the user if it doesn't yet exist or edit the existing one, you need to first check if there's an Adult instance for the user:

@login_required                              
def lexuseditform(request):
    try:
        adult = Adult.objects.get(user=request.user)
    except Adult.DoesNotExist:
       adult = Adult(user=request.user)
    #... your code here

Also note that I removed the userpk argument and test against request.user.pk which is useless if you think about it.

Upvotes: 1

Related Questions