3

I followed some questions on this site to add a new column in the Django admin based on a model method. It works great. However, I cannot sort on the column. Is there a way to accomplish a sort on a model method field where there is no physical model field to reference?

For example one method looks up a foreign key relationship to another model and it returns strings. They could be alphabetically sorted. Another example checks to see if the model is active based on whether there is a termination date or not. (Obviously I can easily add a boolean field to the model, but I want to know if this can be accomplished by just using methods instead). Is there a way to enable sorting on these "columns"?

Update: this is a non-rel backend (mongo), so foreign key lookups won't natively work.

Ex.

class mymodel(models.Model):
    user = models.ForeignKey(User)
    termination_date = models.DateTimeField(blank=True, null=True)

    # Useful admin view methods
    # Returns whether the model is currently active.
    def is_active(self):
        if self.termination_date:
            return False
        else:
            return True

    is_active.boolean = True
    is_active.admin_order_field = 'termination_date' #<--- This activates sort, but not on the boolean, it sorts on the Model Field termination_date.

    # Returns the username from foreign key relationship
    def get_username(self):
        return User.objects.get(pk=self.user_id).username

    get_username.short_description = 'user'
James
  • 2,488
  • 2
  • 28
  • 45
  • Can you do `MyModel.objects.all().order_by('user__username')`? I mean, forget the admin site for a second, can you order the QuerySet object according to the related username **using the non-rel ORM** (not python)? – yuvi Feb 16 '14 at 10:56

1 Answers1

2

The admin uses the database to sort the results, so if your method cannot be mapped directly to a database field (as your example with admin_order_field shows) you can't sort on it.

That said, your get_username method isn't necessary - it can be replaced with a foreign key lookup. Starting with 1.3 (I think) you can use standard __ field references in admin settings, eg:

list_display = ('is_active', 'user__username')

And in that case the column will be sortable, since user__username is a database column. I believe that if you needed to perform more manipulation on the username than just showing it unedited, you could set user__username as the admin_order_field for your method.

Peter DeGlopper
  • 36,326
  • 7
  • 90
  • 83
  • Sorry, I forgot to mention I'm using a non-rel backend (mongo), so the foreign key lookups won't work. This is why I needed to use the `get_username` method. But you are pretty certain sorting on a model method isn't quite possible? – James Feb 16 '14 at 05:43