#8795 closed (fixed)
unique_together validation fails on model forms that exclude unique fields
Reported by: | Owned by: | Jacob | |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
i found this bug
when you have model like this:
class FunkcjeProdukt(models.Model): funkcja = models.ForeignKey(FunkcjeRodzina) produkt = models.ForeignKey(Produkty) wartosc = models.CharField(max_length=255) class Meta: unique_together = ("produkt", "funkcja")
and form from model:
class FunkcjeProduktForm(ModelForm): wartosc = forms.CharField(widget=forms.TextInput(attrs={'size':'40','class':'formularz'})) class Meta: model = FunkcjeProdukt exclude=('produkt','funkcja')
end if you want only edit "wartosc" from existing instance:
form_fp = FunkcjeProduktForm(data=request.POST,instance=finst) if form_fp.is_valid(): form_fp.save()
error is throw:
KeyError at /cms/r_produkt/8/'produkt' Request Method: POST Request URL: http://posiflex.com.pl/cms/r_produkt/8/ Exception Type: KeyError Exception Value: 'produkt' Exception Location: /home/posiflex/django/forms/models.py in validate_unique, line 238
because:
in validate_unique() from django/forms/models.py
line unique_checks = list(self.instance._meta.unique_together[:])
add 'produkt' and 'funkcja' even when this fields in on exclude list
Attachments (1)
Change History (13)
comment:1 by , 16 years ago
Description: | modified (diff) |
---|
comment:2 by , 16 years ago
Summary: | bug in form validation → unique_together validation fails on model forms that exclude unique fields |
---|
(Changed title so I'll understand what's going on quicker.)
comment:3 by , 16 years ago
My call here is "don't do that". You shouldn't save the form if you know the model instance can't be complete. It's actually normal that it fails: the form is valid, the instance is not.
If for example you had a required field your model, but that was excluded in the form. form.save()
would also fail, and for a good reason.
I would use form.save(commit=False)
in your code instead, and then manually fix the problematic fields.
comment:4 by , 16 years ago
instance is valid im 100% sure, in this situation first program create instance with "produkt" and "funkcja" complete then in other place user can only modified one field "wartosc" and this traceback show this place:
lookup_kwargs[field_name] = self.cleaned_data[field_name]
this list self.cleaned_data doesnt have 'produkt' key so bug truly exist
comment:5 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
It's not form.save()
that's failing; it's form.is_valid()
; this is indeed a bug. It's a pretty easy fix; I'll have it done soon.
comment:8 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:9 by , 16 years ago
A question concerning the fix.
Given a model like that:
class Project(models.Model): name = models.CharField(_('Name'), max_length=255) creator = models.ForeignKey(User, verbose_name=_('Ersteller'), related_name='projects') class Meta: unique_together = ('name', 'creator')
And a form like that:
class ProjectForm(forms.ModelForm): class Meta: model = Project fields = ['name']
form.is_valid() doesn't report the failed constraint, only when I include in the creator field in the fields array too. Seems as the check is broken (or impossible), if only one part of the unique_together constraint is inside the fields list.
Is this a bug or just a case I have to live with, cause it is not solvable?
comment:10 by , 16 years ago
If you can come up with a test case which is similar to the one added in [8854] and which fails, then yes, you should reopen this ticket.
comment:11 by , 16 years ago
In reply to comment:9, the form is valid. The unique_together constraint is only applicable to the model and thus is only going to kick in at save time at the moment. With the model-aware validation work in progress, there'll be an extra step to check the model validity as well, prior to saving so that validation errors there can be handled properly rather than being raised out of save()
.
Rewrote Description to hightlight code and not mess with it.