Opened 19 years ago
Closed 18 years ago
#1839 closed defect (fixed)
ForeignKey('self') with attribute name like model name breaks AddManipulator().save()
Reported by: | Owned by: | Adrian Holovaty | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | normal | Keywords: | |
Cc: | django@…, gabor@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I use this model:
class Another(models.Model): name = models.CharField(maxlength=20, core=True) another = models.ForeignKey('self', null=True, related_name='child_set')
Note that the field name another
is like the model name, only lower case.
The following code fails:
Another.AddManipulator().save(dict(id='3', name='Another root category', another=None))
This might be an intended restriction, but then it should be checked by model validation. When it strikes, it's rather surprising because you don't see any connection to the attribute name in the backtrace. And it's probably a common thing to name the self relationship after the table.
This is the exception:
Exception: File "/home/mir/src/django/trunk/tests/doctest.py", line 1243, in __run compileflags, 1) in test.globs File "<doctest m2o_recursive[10]>", line 1, in ? anotherone = Another.AddManipulator().save(dict(id='3', name='Another root category', another=None)) File "/home/mir/src/django/active/django/db/models/manipulators.py", line 75, in __init__ self.fields.extend(f.get_manipulator_fields(self.opts, self, self.change, fol)) File "/home/mir/src/django/active/django/db/models/related.py", line 112, in get_manipulator_fields if follow.get(f.name, False): AttributeError: 'bool' object has no attribute 'get'
db.models.related.RelatedObject.get_manipulator_fields expects a dictionary in follow. But db.models.maniplators.init() sends True
.
Attachments (2)
Change History (17)
by , 19 years ago
by , 19 years ago
Attachment: | m2o_recursive.diff added |
---|
... or as a patch to existing m2o_recursive test, if you prefer
comment:2 by , 18 years ago
Sorry. I do search, but sometime I overlook things.
Anyway, ticket #1826 demonstrates that *any* field that has the same name as the attribute is sufficient to trigger this bug when there's a ForeignKey('self') *anywhere* in the model. It needn't be the ForeignKey field itself.
comment:3 by , 18 years ago
Cc: | added |
---|
comment:4 by , 18 years ago
Note: This is very similar to #2216 (Filtering by a field having same name as the model results in AttributeError)
comment:5 by , 18 years ago
Doesn't appear to be the same problem as #2216. There is no clash in query terms/accessors - the problem seems to be in the construction of the follow term for related fields.
comment:6 by , 18 years ago
Owner: | changed from | to
---|
comment:7 by , 18 years ago
Cc: | added |
---|
comment:8 by , 18 years ago
Owner: | changed from | to
---|
This should be cleaned up as part of the manipulator refactoring effort.
comment:10 by , 18 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:11 by , 18 years ago
although manipulators will be going away when newforms is complete, so this might not be worth fixing.
comment:12 by , 18 years ago
newforms-admin will indeed fix this; the problem is with the follow
dict for manipulators.
comment:13 by , 18 years ago
Needs tests: | set |
---|
Even if this doesn't get fixed in manipulators, we should make certain it works with newforms with some tests.
comment:14 by , 18 years ago
comment:15 by , 18 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
(In [4676]) Fixed #1839, #2415, #2536 -- Fixed a generated name clash that was common in
self-referential and circular relations. A lot of community debugging went into
this fix, so thanks to bmurdock@…, Marek Kubica, ramiro, Michael
Radziej (the last two giving test cases showing the problem) and James Bennett
(who did the hard work to actually diagnose the true problem and fix it).
unit test demonstrating this problem