Opened 16 years ago
Closed 16 years ago
#8882 closed (fixed)
Inline model formsets break validation for unique and unique_together with foreign keys
Reported by: | Owned by: | Brian Rosner | |
---|---|---|---|
Component: | Forms | Version: | 1.0 |
Severity: | Keywords: | model-validation | |
Cc: | gabor@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The admin site fails when trying to create two registers (not unique) on a model with unique or unique together fields. It doesn't check for the unique statement and database backend raises an IntegrityError exception like this:
IntegrityError at /admin/myapp/mymodel/add/
(1062, "Duplicate entry '2-1' for key 2")
I haven't checked if the problem exists in "handmade" forms, but in admin site it fails.
Attachments (1)
Change History (17)
comment:1 by , 16 years ago
Summary: | Unique and Unique together in admin inlines is not working → Unique and Unique together in admin inlines are not working |
---|
comment:2 by , 16 years ago
comment:3 by , 16 years ago
Component: | Admin interface → Forms |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:5 by , 16 years ago
Summary: | Unique and Unique together in admin inlines are not working → Inline model formsets break validation for unique_together with foreign keys |
---|
Given the following models.py
:
from django.db import models from django import forms from django.contrib import admin class Foo(models.Model): foo = models.CharField(max_length=100) # test for unique class Bar(models.Model): foo = models.ForeignKey(Foo) bar = models.CharField(max_length=100, unique=True) # test for unique_together class Baz(models.Model): foo = models.ForeignKey(Foo) baz = models.CharField(max_length=100) class Meta: unique_together = ("foo", "baz") class BarInline(admin.StackedInline): model = Bar class BazInline(admin.StackedInline): model = Baz class FooAdmin(admin.ModelAdmin): inlines = (BarInline, BazInline) admin.site.register(Foo, FooAdmin)
Test case 1 -- the database is empty:
- adding
Bar.bar = 'a'
twice results inIntegrityError at /admin/uniq/foo/add/ -- column bar is not unique
, - adding a single
Bar.bar = 'a'
and consequently addingBaz.baz = 'a'
twice results inIntegrityError at /admin/uniq/foo/1/ -- columns foo_id, baz are not unique
Test case 2 -- there is already a Bar
with Bar.bar = 'a'
:
- adding
Bar.bar = 'a'
again is correctly validated andBar with this Bar already exists.
displayed, - adding a single
Bar.bar = 'b'
and consequently addingBaz.baz = 'a'
twice results inIntegrityError at /admin/uniq/foo/1/ -- columns foo_id, baz are not unique
comment:6 by , 16 years ago
Summary: | Inline model formsets break validation for unique_together with foreign keys → Inline model formsets break validation for unique and unique_together with foreign keys |
---|
comment:7 by , 16 years ago
Something the reported in #8890 commented in that ticket that might be of some help: "It appears that the inlineformset_factory helper removes the foreign key field from the produced forms, which prevents validate_unique from actually validating like it is supposed to."
comment:8 by , 16 years ago
This is a short slice of code from django/forms/models.py
def validate_unique(self): from django.db.models.fields import FieldDoesNotExist # Gather a list of checks to perform. Since this is a ModelForm, some # fields may have been excluded; we can't perform a unique check on a # form that is missing fields involved in that check.
The real problem is that the foreign key to the "parent" model in the 1-* relation is missing
comment:9 by , 16 years ago
Cc: | added |
---|
comment:10 by , 16 years ago
Keywords: | model-validation added |
---|
comment:11 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
by , 16 years ago
Attachment: | formset-unique.diff added |
---|
comment:12 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:13 by , 16 years ago
comment:14 by , 16 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
brosner, the fix is unfortunately insufficient. Alex's patch is also needed, but as that deals with unique
checks only, unique_together
checks need still to be added to it.
Try the testcase that I've reported above.
I'll examine the code hopefully tomorrow and write a patch.
comment:15 by , 16 years ago
This revision causes bug: http://dpaste.com/88174/.
Bug appears when Inline have fieldsets. In the same time, can you add this: http://code.djangoproject.com/ticket/9025 ?
Thank you.
comment:16 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
I suppose the problem that Alex was patching was indeed described here. There were really *two* issues hidden in this ticket (including all the tickets marked as duplicates). I fixed the one where the foreign key is involved in unique_together didn't work before. Lets not make this more confusing that it needs to be. To isolate the issues lets open new tickets. It will be much easier to track. Alex Gaynor has opened #9493 to track the issue mrts brought up in the reopen. It is a valid issue.
Fugazi, like I said above, lets open a new ticket with *detailed* information about the problem please. #9025 has absolutely nothing to do with any of this.
Can you please construct a small example model that demonstrates the problem you are talking about. That way there's no chance of confusion as to whether we're debugging the problem you are reporting or not.