Reputation: 3075
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
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
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