#9498 closed (fixed)
generic inline formsets: object has no attribute 'fk'
| Reported by: | Fred Bartle | Owned by: | Brian Rosner |
|---|---|---|---|
| Component: | Contrib apps | Version: | dev |
| Severity: | Keywords: | generic inline formsets | |
| Cc: | Carl Meyer, Ben Spaulding | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Attachments (4)
Change History (14)
by , 17 years ago
| Attachment: | generic.py.r9329.diff added |
|---|
comment:1 by , 17 years ago
| Has patch: | set |
|---|---|
| Needs tests: | set |
comment:2 by , 17 years ago
comment:3 by , 17 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
| Triage Stage: | Unreviewed → Accepted |
comment:4 by , 17 years ago
applying the patch helped, but directly showed a new bug:
http://nopaste.com/p/aJeKlSyvj
looking into contrib/contenttypes/generic.py I found this:
if exclude is not None:
exclude.extend([ct_field.name, fk_field.name])
else:
exclude = [ct_field.name, fk_field.name]
makes no sense to me, but i'm not the architect ;)
So i'm attaching another patch, which includes the first and
deletes the whole "else" - for me this fixes GenericTabularInline
by , 17 years ago
| Attachment: | generic.py.r9329_2.diff added |
|---|
comment:5 by , 17 years ago
so once again:
after some testing i've seen, that those lines:
if exclude is not None:
exclude.extend({ct_field.name, fk_field.name})
else:
exclude = [ct_field.name, fk_field.name]
Are indeed _not_ useless! It's absolutly clear (now - for me - finally), that
we of course don't need the ForeignKey in a GenericInlineFormSet, because it's
clear that we set the ForeignKey according the Model we are "inlining". So without
the "else" from the snippet, I always had a content_type and object_id field in
my inline-form, what seems to be a new-self-produced-bug - means: re-add those two
lines and restart searching, why I always get: http://nopaste.com/p/aJeKlSyvj
The problem with this is, the fk_field is beeing called directly from the template,
so there is no way to avoid beeing asked for the fk_field-widget. As mentioned before,
we have absolutly no need for the fk-field, as it gets set automaticly by the parent
model. So i just looked for the output-method for fk_field - in contrib/admin/helpers.py:
def fk_field(self):
return AdminField(self.form, self.formset.fk.name, False)
inside "InlineAdminForm", means for me only inlined-models come across this form,
so it's painless to just change it to:
def fk_field(self):
try:
return AdminField(self.form, self.formset.fk.name, False)
except KeyError, e:
return ""
This actually is just a silent failure, which still works if needed.
(Isn't this anyway planned/recommended for template-parsing?)
So there is another file attached, including this and the first patch.
Do _NOT_ use the second patch, it's more an ugly hack than a solution ;)
hope i could help,
greets
by , 17 years ago
| Attachment: | generic.py_helpers.py_r9329.diff added |
|---|
comment:6 by , 17 years ago
| Cc: | added |
|---|
comment:7 by , 17 years ago
| Cc: | added |
|---|
by , 17 years ago
| Attachment: | generic_inline_tests.diff added |
|---|
comment:9 by , 17 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
(In [9413]) [1.0.X] Fixed #9498 -- Handle a formset correctly when the foreign key is not available (for now).
This case pops up with generic foreign key inlines after [9297]. Added tests
to handle future regressions with generic foreign key inlines in the admin.
Thanks markus and danielr for patches.
Backport of [9412] from trunk.
Here's a basic example:
class Attribute(models.Model): content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') key = models.CharField(max_length=30) value = models.CharField(max_length=30) class MyModel(models.Model): name = models.CharField(max_length=30) attributes = generic.GenericRelation(Attribute) class AttributeInline(generic.GenericTabularInline): model = Attribute class MyModelAdmin(models.Model): inlines = [AttributeInline]