Django: Sort filter_name-list of a ManyToManyRelation in Admin

28. December 2008

Assume you have a Category model and a Post model. In the Post model the Category is related using a ManyToManyField

category = models.ManyToManyField(Category)

In the admin you want to filter by category. To achieve this add

list_filter = ['category']

to the PostOptions class in admin.py. The problem now is, that you have a lot of categories and want them sorted by name. The idea for this solution was inspired by http://www.djangosnippets.org/snippets/1051/ but is much simpler. One solution for this problem is

from django.contrib.admin.filterspecs import FilterSpec, RelatedFilterSpec

class AlphabeticRelatedFilterSpec(RelatedFilterSpec):
    """
    Adds filtering by __unicode__-value of a ManyToMany-Relation in the admin
    filter sidebar. Set the alphabetic filter in the model field attribute
    'alphabetic_filter'.

    my_model_field.alph_rel_filter = True
    """

    def __init__(self, f, request, params, model, model_admin):
        super(AlphabeticRelatedFilterSpec, self).__init__(f, request, params, model,
                                                   model_admin)
        self.lookup_choices = sorted(f.get_choices(include_blank=False), 
                                     key=lambda x:(x[1], x[0]))

# registering the filter
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'alph_rel_filter', False),
                                   AlphabeticRelatedFilterSpec))

Add this to /admin/filterspecs.py and import .admin.filterspecs in your url.py.

This is a special problem but I hope this helps someone.

Tags: admin, django, python

Categories: Django, Projects

 
 

Write new Comment

captcha