Django

Code

Ticket #9498 (closed: fixed)

Opened 1 year ago

Last modified 1 year ago

generic inline formsets: object has no attribute 'fk'

Reported by: fredbartle Assigned to: brosner
Milestone: Component: Contrib apps
Version: SVN Keywords: generic inline formsets
Cc: carljm, benspaulding Triage Stage: Accepted
Has patch: 1 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

Description

As of r9297, which django.contrib.admin.helpers now utilizes formset.fk, generic inline formsets now break attempting to access formset.fk. Attached is a simple fix, though I suspect there's more work to be done with generic and r9297.

Attachments

generic.py.r9329.diff (504 bytes) - added by fredbartle on 11/02/08 10:16:53.
generic.py.r9329_2.diff (0.7 kB) - added by markus _forgot_ evigo _spam_ net on 11/02/08 12:54:46.
generic.py_helpers.py_r9329.diff (0.9 kB) - added by markus _uploading_ evigo _patch_ net on 11/02/08 15:58:29.
generic_inline_tests.diff (6.1 kB) - added by danielr on 11/11/08 05:59:21.

Change History

11/02/08 10:16:53 changed by fredbartle

  • attachment generic.py.r9329.diff added.

11/02/08 10:17:17 changed by fredbartle

  • needs_better_patch changed.
  • has_patch set to 1.
  • needs_tests set to 1.
  • needs_docs changed.

11/02/08 10:23:43 changed by fredbartle

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]

11/02/08 11:57:03 changed by brosner

  • owner changed from nobody to brosner.
  • status changed from new to assigned.
  • stage changed from Unreviewed to Accepted.

11/02/08 12:53:14 changed by markus@evigo.net

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?

11/02/08 12:54:46 changed by markus _forgot_ evigo _spam_ net

  • attachment generic.py.r9329_2.diff added.

11/02/08 15:57:02 changed by markus _presents_a_better_ evigo _solution_ net

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

11/02/08 15:58:29 changed by markus _uploading_ evigo _patch_ net

  • attachment generic.py_helpers.py_r9329.diff added.

11/03/08 07:32:45 changed by carljm

  • cc set to carljm.

11/05/08 14:11:22 changed by benspaulding

  • cc changed from carljm to carljm, benspaulding.

11/11/08 05:59:21 changed by danielr

  • attachment generic_inline_tests.diff added.

11/11/08 06:00:15 changed by danielr

  • needs_tests deleted.

Patch that adds regression tests for this problem.

11/13/08 13:05:49 changed by brosner

  • status changed from assigned to closed.
  • resolution set to fixed.

(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.

11/13/08 13:06:34 changed by brosner

This was also applied on trunk in [9412] -- dang post-commit hook :)


Add/Change #9498 (generic inline formsets: object has no attribute 'fk')




Change Properties
Action