Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#25622 closed Bug (fixed)

InlineAdmin raises 'GenericRel' object has no attribute 'get_related_field'

Reported by: Jonathan Liuti Owned by: Simon Charette
Component: contrib.admin Version: 1.8
Severity: Normal Keywords:
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

I have the following setup (simplified for the sake of clarity)

# models.py
class ModelA(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    uuid = models.UUIDField(default=uuid.uuid4, unique=True, db_index=True)

class ModelB(models.Model):
    model_a_fk = models.ForeignKey('ModelA', to_field='uuid')
    model_c_fk = models.ForeignKey('ModelC')

class ModelC(models.Model):
    ... # nothing fancy
#admin.py
class ModelAAdmin(admin.ModelAdmin):
    .... #nothing fancy

class InlineModelB(admin.TabularInline):
     model=ModelB
     raw_id_fields=('model_a_fk', 'model_c_fk')

class ModelBAdmin(admin.ModelAdmin):
     raw_id_fields=('model_a_fk', 'model_c_fk')

class ModelCAdmin(admin.ModelAdmin):
     inlines=(InlineModelB,)

Now, when going to the ModelCAdmin view, triggering the search pop-up for ModelB.model_a_fk field, I will get the following traceback:

  File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 132, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py", line 616, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py", line 110, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py", line 233, in inner
    return view(request, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py", line 34, in _wrapper
    return bound_func(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py", line 110, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py", line 30, in bound_func
    return func.__get__(self, type(self))(*args2, **kwargs2)
  File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py", line 1548, in changelist_view
    self.list_max_show_all, self.list_editable, self)
  File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/views/main.py", line 67, in __init__
    if to_field and not model_admin.to_field_allowed(request, to_field):
  File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py", line 489, in to_field_allowed
    related_object.field.rel.get_related_field() == field):
AttributeError: 'GenericRel' object has no attribute 'get_related_field'

Triggering the search pop-up for ModelB.model_c_fk works just fine.

It looks like https://code.djangoproject.com/ticket/23616 but in a different place.

Change History (11)

comment:1 by Simon Charette, 8 years ago

Owner: changed from nobody to Simon Charette
Status: newassigned

comment:2 by Simon Charette, 8 years ago

Resolution: worksforme
Status: assignedclosed

Hi johnraz,

This looks like a legitimate traceback but I cannot reproduce with your provided setup against 1.8.x and master.

Can you confirm I didn't miss something?

comment:3 by Simon Charette, 8 years ago

Do you have a django.contrib.contenttypes.fields.GenericRelation defined somewhere?

comment:4 by Jonathan Liuti, 8 years ago

Yes you are absolutely right.
I do have a GenericRelation setup like this (in addition to the previous example):

# models.py

class AbstractModelX(models.Model):
    model_a_gen_rel = GenericRelation(ModelA)
    class Meta:
        abstract=True

class ModelD(AbstractModelX):
    pass

class ModelE(AbstractModelX):
    pass
Last edited 8 years ago by Jonathan Liuti (previous) (diff)

comment:5 by Simon Charette, 8 years ago

Resolution: worksforme
Status: closednew

Will look into this soon.

comment:6 by Simon Charette, 8 years ago

Has patch: set
Triage Stage: UnreviewedAccepted

Managed to reproduced with simplified models, thanks. Here's a PR you can test.

I guess we should backport this since it's a bug in a new feature.

comment:7 by Tim Graham, 8 years ago

Triage Stage: AcceptedReady for checkin

comment:8 by Jonathan Liuti, 8 years ago

Splendid !
It works for me.

comment:9 by Simon Charette <charette.s@…>, 8 years ago

Resolution: fixed
Status: newclosed

In 9dcfecb:

Fixed #25622 -- Accounted for generic relations in the admin to field validation

Thanks to Jonathan Liuti for the report and Tim Graham for the review.

comment:10 by Simon Charette <charette.s@…>, 8 years ago

In 6eaf43a2:

[1.9.x] Fixed #25622 -- Accounted for generic relations in the admin to field validation

Thanks to Jonathan Liuti for the report and Tim Graham for the review.

Backport of 9dcfecb7c6c8285630ad271888a9ec4ba9140e3a from master

comment:11 by Simon Charette <charette.s@…>, 8 years ago

In c42e4e7:

Fixed #25622 -- Accounted for generic relations in the admin to field validation

Thanks to Jonathan Liuti for the report and Tim Graham for the review.

Conflicts:

django/contrib/admin/options.py

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