Starting with
{{{
class SupportItem(models.Model):
description = models.CharField(max_length=30)
class Hardware(SupportItem):
tag = models.IntegerField(unique=True)
}}}
and
{{{
class Placement(models.Model):
support_item = models.ForeignKey("SupportItem")
place_date = models.DateTimeField()
location = models.CharField(max_length=50, null=True, blank=True)
}}}
I have defined a view on the database exposed in Django as
{{{
class HardwareLastAssigned(models.Model):
hardware = models.OneToOneField(Hardware, primary_key=True,
db_column='support_item_id',
related_name='last_assigned')
location = models.CharField(max_length=50, blank=True)
}}}
which gives the last location a hardware item was deployed to.
Under Django 1.7, the following admin code produces a changelist showing
each piece of hardware and its current location:
{{{
class HardwareAdmin(NavigableModelAdmin):
list_display = ['tag', 'placement']
list_display_links = list_display
search_fields = ['tag', 'last_assigned__location']
form = HardwareForm
...
def placement(self, obj):
return obj.last_assigned.location
def get_queryset(self, request):
hardware = super(HardwareAdmin, self).get_queryset(request)
hardware = hardware.select_related("last_assigned")
return hardware
}}}
Following an upgrade to Django 1.8, the same code crashes with this
exception:
AttributeError: 'Hardware' object has no attribute 'placement'
in
File "/home/django/python2.7-django1.8/lib/python2.7/site-
packages/django/contrib/admin/utils.py", line 288, in lookup_field
value = getattr(obj, name)
The cause lies in Options.get_field() (django.db.models.options) which
under 1.7 only recognized true fields on the model at hand (Hardware),
whereas under 1.8, it also reports related models as fields on the model.
However, lookup_field can only handle true fields and triggers the
exception.
A workaround is to rename the callable so it does not match any related
names which may be associated with the model.
The change was made in commit fb48eb05816b1ac87d58696cdfe48be18c901f16 as
part of the formalizations of the _meta API.
If nothing else can be done, it may be worth a mention in the list_display
documentation as this restriction is not at all obvious (to me) based on
the current docs and the 1.8 release notes.
--
Ticket URL: <https://code.djangoproject.com/ticket/25299>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* severity: Normal => Release blocker
* needs_better_patch: => 0
* component: Uncategorized => contrib.admin
* needs_tests: => 0
* needs_docs: => 0
* stage: Unreviewed => Accepted
Comment:
This looks like a bug we should fix. Attaching a regression test for
Django's test suite. Feel free to tackle it if you have some time.
--
Ticket URL: <https://code.djangoproject.com/ticket/25299#comment:1>
* Attachment "25299-test.diff" added.
* status: new => assigned
* owner: nobody => timgraham
--
Ticket URL: <https://code.djangoproject.com/ticket/25299#comment:2>
* has_patch: 0 => 1
Comment:
[https://github.com/django/django/pull/5185 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/25299#comment:3>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"9607a0404188bbe612f05216f5a82df26f4b4e80" 9607a04]:
{{{
#!CommitTicketReference repository=""
revision="9607a0404188bbe612f05216f5a82df26f4b4e80"
Fixed #25299 -- Fixed crash with ModelAdmin.list_display value that
clashes with a model reverse accessor.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25299#comment:4>
Comment (by Tim Graham <timograham@…>):
In [changeset:"3cc67a637a3cd1426d2ac87d7418600fa247ebb2" 3cc67a6]:
{{{
#!CommitTicketReference repository=""
revision="3cc67a637a3cd1426d2ac87d7418600fa247ebb2"
[1.8.x] Fixed #25299 -- Fixed crash with ModelAdmin.list_display value
that clashes with a model reverse accessor.
Backport of 9607a0404188bbe612f05216f5a82df26f4b4e80 from master
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/25299#comment:5>