Is it possible to 'order' the left side of a filter_horizontal?

1,853 views
Skip to first unread message

rc

unread,
Nov 25, 2009, 3:06:52 PM11/25/09
to Django users
I have configured a modeladmin which uses the filter_horizontal
feature. I would like to be able to order left side of this feature by
name instead of the default (which I believe is by id). Is this
possible? I see how to use "ordering" in the display for change lists,
but not sure how to apply that to the 'left' side data of the
filter_horizontal.

Tim Valenta

unread,
Nov 25, 2009, 3:50:24 PM11/25/09
to Django users
Well, you've got a couple of options. One is easiest and most
straightforward, but could impact performance. The second is a little
bit more work, but would limit the ordering to only taking effect on
that one form.

The first way is to use the Meta option `ordering = ('fieldname',)`,
as described here:
http://docs.djangoproject.com/en/dev/ref/models/options/#ordering

Bare in mind that this will passively affect ALL queries you do to
that model's objects, unless you specifically tell it not to order
during the query. If you think that you'll *always* want that sort
order to take effect, then this is the preferred method of
accomplishing that.

The second way is to intercept the form's queryset powering the
widget. If you're not using Form objects with your admin (ie, you're
just specifying 'fields' or 'fieldsets' on your ModelAdmin), then
you'll have to take a quick sidequest:

Create a class somewhere (preferably in your app's directory, in a
"forms.py" file or something obvious) like so:

from django import forms
from models import MyModel
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
def __init__(self, *args, **kwargs):
forms.ModelForm.__init__(self, *args, **kwargs)
self.fields['myfieldname'].queryset =
MyModel.objects.order_by('custom_sort_field_name')

And then back in your ModelAdmin, add this attribute to the class:

# ...
from forms import MyModelForm
form = MyModelForm

This will cause the admin to use *your* form instead of the default.
What I've done is created a form which simply hijacks the queryset on
'myfieldname' (the field you're trying to sort), and alters it before
the widget has a chance to render itself.


Both methods are effective, but be sure to consider my initial
statement, about performance impact. Pick the method that strikes the
balance in your mind between performance and practicality.

Hope that helps!

rc

unread,
Nov 30, 2009, 11:22:07 AM11/30/09
to Django users
Tim,

The ordering meta option on my model did the trick. Thanks for the
solution.

Reed

SeanSF

unread,
Jan 27, 2010, 6:13:38 PM1/27/10
to Django users
I just had the same question, and the meta 'ordering' did the trick.
Thanks Reed and Tim!
Reply all
Reply to author
Forward
0 new messages