jason
jason

Reputation: 3075

django view integrityError

I need help with the following code. I think I'm almost there. I'm trying to create a view with works for both editing and adding a new object. However, on saving I get the error listed below.

I wonder if someone can show me where I'm going wrong?

Thank you.

view.py

def group(request, id=None):

    if id:
        group = get_object_or_404(Groups, pk=id)

    else:
        group = Groups()

        # If we had a POST then get the request post values.
    if request.method == 'POST':
        form = GroupFrom(request.POST)
        # Check we have valid data
        if form.is_valid():
            group = Groups(
                name=form.cleaned_data['name'],
                description=form.cleaned_data['description'],
                active=form.cleaned_data['active'],
                user=request.user
            )

            group.save()

    else:
        form = GroupFrom(instance=group)

    context = {'form': form}
    return render_to_response('contacts/group.html', context, context_instance=RequestContext(request))

urls.py

     (r'^group/new/$', 'contacts.views.group', {}, 'group_new'),
     (r'^group/edit/(?P<id>\d+)/$', 'contacts.views.group', {}, 'group_edit'),

model.py

class Groups(models.Model):
    """
     Stores all groups.
    """
    name = models.CharField(max_length=60)
    description = models.TextField(max_length=250)
    active = models.BooleanField()
    modified = models.DateTimeField(null=True, auto_now=True, help_text="Shows when object was modified.")
    created = models.DateTimeField(auto_now_add=True, help_text="Shows when object was created.")

    #FK
    user = models.ForeignKey(User, unique=True, related_name="user")

    def __unicode__(self):
        return self.name

error

IntegrityError at /contacts/group/edit/1/ (1062, "Duplicate entry '1' for key 'user_id'")

UPDATE: So this is what I have now, and it works, but only on edit not add. On add I still get the same error:

def group(request, id=None):

    if id:
        # If we have an id try and get it and populate instance.
        group = get_object_or_404(Groups, pk=id)
        # If we have an instance check that it belongs to the login.
        if group.user != request.user:
            return HttpResponseForbidden()
    else:
        # If we don't have an id get the instance (which is blank here) and populate it with the user.
        group = Groups(user=request.user)

    # If we had a POST then get the request post values.
    if request.method == 'POST':
    # Populate the form with the instance.
        form = GroupFrom(request.POST, instance=group)
        # Check we have valid data before saving trying to save.
        if form.is_valid():
            group.save()
            messages.add_message(request, messages.SUCCESS, 'Successfully Created/Updated Group')

    else:
        # Populate from at this point group with either be blank or have values.
        form = GroupFrom(instance=group)

    context = {'form': form}
    return render_to_response('contacts/group.html', context, context_instance=RequestContext(request))

Upvotes: 0

Views: 830

Answers (2)

Brandon Taylor
Brandon Taylor

Reputation: 34553

You can shorten up your code quite a bit:

class GroupForm(forms.ModelForm):
    class Meta:
        model = Group

    def __init__(self, *args, **kwargs)
        user = kwargs.pop('user')
        super(GroupForm, self).__init__(*args, **kwargs)
        self.user = user

def group(request, id=None):
    if id:
        instance = get_object_or_404(Groups, pk=id)
    else:
        instance = None

    form = GroupFrom(request.POST or None, instance=instance, user=request.user)

    if request.method == 'POST':
        if form.is_valid():
            group = form.save()
    return render_to_response('contacts/group.html', {'form': form},
        context_instance=RequestContext(request))

A simple override of the GroupForm's __init__ allows you to hand in the user from the request, saving you from having to manually assign the value in the view. The or statement in the form's initialization allows you to do the instantiation in one place, rather than have a separate method if it's a GET request.

You have unique=True on your user foreign key property. Manually assigning it in the view won't catch any validation. Assigning the property when the form is instantiated should trigger a validation error before the form is submitted.

Upvotes: 1

Ponytech
Ponytech

Reputation: 1684

Try to replace

            group = Groups(
            name=form.cleaned_data['name'],
            description=form.cleaned_data['description'],
            active=form.cleaned_data['active'],
            user=request.user
        )

by :

        group.name=form.cleaned_data['name']
        group.description=form.cleaned_data['description']
        group.active=form.cleaned_data['active']
        group.user=request.user

Your group = Groups( is just erasing the previous value of the group variable.

Upvotes: 1

Related Questions