Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#22994 closed Bug (fixed)

"'GenericForeignKey' object has no attribute 'opts'" exception on 1.7

Reported by: glicerinu@… Owned by: Tim Graham <timograham@…>
Component: contrib.contenttypes Version: 1.7-rc-1
Severity: Release blocker Keywords: GenericForeignKey content_object opts list_display
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Django raises a "'GenericForeignKey' object has no attribute 'opts'" when using 'content_object' on a ModelAdmin.list_display

Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  137.                 response = response.render()
File "/usr/local/lib/python2.7/dist-packages/django/template/response.py" in render
  103.             self.content = self.rendered_content
File "/usr/local/lib/python2.7/dist-packages/django/template/response.py" in rendered_content
  80.         content = template.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  148.             return self._render(context)
File "/usr/local/lib/python2.7/dist-packages/django/test/utils.py" in instrumented_test_render
  88.     return self.nodelist.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/usr/local/lib/python2.7/dist-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py" in render
  126.         return compiled_parent._render(context)
File "/usr/local/lib/python2.7/dist-packages/django/test/utils.py" in instrumented_test_render
  88.     return self.nodelist.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/usr/local/lib/python2.7/dist-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py" in render
  126.         return compiled_parent._render(context)
File "/usr/local/lib/python2.7/dist-packages/django/test/utils.py" in instrumented_test_render
  88.     return self.nodelist.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/usr/local/lib/python2.7/dist-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/usr/local/lib/python2.7/dist-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/loader_tags.py" in render
  65.                 result = block.nodelist.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  844.                 bit = self.render_node(node, context)
File "/usr/local/lib/python2.7/dist-packages/django/template/debug.py" in render_node
  80.             return node.render(context)
File "/usr/local/lib/python2.7/dist-packages/django/template/base.py" in render
  1207.                     _dict = func(*resolved_args, **resolved_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/templatetags/admin_list.py" in result_list
  307.     headers = list(result_headers(cl))
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/templatetags/admin_list.py" in result_headers
  101.             return_attr=True
File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/utils.py" in label_for_field
  305.             label = field.opts.verbose_name

Exception Type: AttributeError at /admin/resources/resourcedata/
Exception Value: 'GenericForeignKey' object has no attribute 'opts'

Attachments (1)

22994-test.diff (2.8 KB) - added by Tim Graham 2 years ago.

Download all attachments as: .zip

Change History (10)

comment:1 Changed 2 years ago by Tim Graham

Did this work in 1.6?

comment:2 Changed 2 years ago by glicerinu@…

Yes, this error appeared after upgrading to 1.7

comment:3 Changed 2 years ago by Tim Graham

Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted

comment:4 Changed 2 years ago by Tim Graham

Owner: changed from nobody to Tim Graham
Status: newassigned

Changed 2 years ago by Tim Graham

Attachment: 22994-test.diff added

comment:6 Changed 2 years ago by Tim Graham

Owner: Tim Graham deleted
Status: assignednew

Added test which passes on 1.6 and fails on master & 1.7.

comment:7 Changed 2 years ago by Tim Graham

Has patch: set
Triage Stage: AcceptedReady for checkin

comment:8 Changed 2 years ago by Tim Graham <timograham@…>

Owner: set to Tim Graham <timograham@…>
Resolution: fixed
Status: newclosed

In 9cd5201abd24ba2632753029ee1957947cdc32f5:

Fixed #22994 -- regression with generic FK + admin list_view

The reason for the regression was that the GenericForeignKey field isn't
something meta.get_field_by_name() should return. The reason is that a
couple of places in Django expects get_field_by_name() to work this way.
It could make sense to return GFKs from get_field_by_name(), but that
should likely be done as part of meta refactoring or virtual fields
refactoring patches.

Thanks to glicerinu@… for the report and to Tim for working on
the issue.

comment:9 Changed 2 years ago by Tim Graham <timograham@…>

In 572885729e028eae2f2b823ef87543b7c66bdb10:

[1.7.x] Fixed #22994 -- regression with generic FK + admin list_view

The reason for the regression was that the GenericForeignKey field isn't
something meta.get_field_by_name() should return. The reason is that a
couple of places in Django expects get_field_by_name() to work this way.
It could make sense to return GFKs from get_field_by_name(), but that
should likely be done as part of meta refactoring or virtual fields
refactoring patches.

Thanks to glicerinu@… for the report and to Tim for working on
the issue.

Note: See TracTickets for help on using tickets.
Back to Top