2

I have a django project with a model that looks like:

class Profile(models.Model):
    #some other stuff
    owner = models.OneToOneField(settings.AUTH_USER_MODEL)
    last_modified = models.DateTimeField(default = timezone.now)

    def __unicode__(self):
        return self.owner.name
    __unicode__.admin_order_field = 'owner__last_name'

My model admin looks something like:

class ProfileAdmin(admin.ModelAdmin):
    ordering = ['-last_modified']
    list_display = ['__unicode__', 'last_modified']

I would like for the admin to be sorted by last_modified by default (as it is now) but to be able to sort alphabetically by clicking on the top of the first column of the list display. I tried to add the __unicode__.admin_order_field line as described here, but that doesn't seem to have made any difference. Is what I want possible? If not why not?

lac
  • 755
  • 10
  • 19
  • Are you using Python 2? I'm not sure whether `admin_order_field` works with double underscores to span foreign keys. Have you tried `__unicode__.admin_order_field='owner'` (it won't give you the result you want, but it will show you if the problem is `'owner__last_name'`. – Alasdair Oct 01 '15 at 14:08
  • Hi @Alasdair, thanks for response. I am using python 2.7 yes. I actually already have another method (that I left out to simplify problem) 'date_joined` with admin_order_field that spans the owner relationship - `date_joined.admin_order_field='owner__date_joined'`. That works fine so I don't think that is the problem. Also if I remove `'__unicode__'` from the list I can sort fine by any of the other fields. – lac Oct 01 '15 at 19:01
  • Looks like you may possible need to use http://django-admin-sortable.readthedocs.org/en/latest/usage.html – dursk Oct 02 '15 at 02:55

1 Answers1

2

You can only sort fields in the django admin interface if they are fields on your model or if they are fields you custom annotate in the get_queryset method of your ModelAdmin class--essentially fields created at the DB level. However, assuming you are deriving your __unicode__ or __str__ method from some fields on your model (and you are--from owner.name) you should be able to reference those fields and make the column sortable like so (though you could use this method to make the unicode field sortable on any model attribute you'd like):

class ProfileAdmin(admin.ModelAdmin):

    def sortable_unicode(self, obj):
        return obj.__unicode__()

    sortable_unicode.short_description = 'Owner Name'
    sortable_unicode.admin_order_field = 'owner__last_name'

    ordering = ['-last_modified']
    list_display = ['sortable_unicode', 'last_modified']

Though I do find it a bit strange that you will be displaying the owner's name but sorting on last_name. This might be a bit puzzling when you wonder why your sort order doesn't match the displayed name in the admin interface.

user1847
  • 3,571
  • 1
  • 26
  • 35