I want to apply the "ordering" Meta option to the Django model User from django.contrib.auth.models. Normally I would just put the Meta class in the model's definition, but in this case I did not define the model. So where do I put the Meta class to modify the User model?
views:
961answers:
4This is how the Django manual recommends you do it:
You could also use a proxy model to define a different default ordering on a model. The standard User model has no ordering defined on it (intentionally; sorting is expensive and we don't want to do it all the time when we fetch users). You might want to regularly order by the username attribute when you use the proxy. This is easy:
class OrderedUser(User):
class Meta:
ordering = ["username"]
proxy = True
Now normal User queries will be unorderd and OrderedUser queries will be ordered by username.
Note that for this to work you will need to have a trunk checkout of Django as it is fairly new.
If you don't have access to it, you will need to get rid of the proxy part and implement it that way, which can get cumbersome. Check out this article on how to accomplish this.
You can either subclass User:
class OrderedUser(User):
class Meta:
ordering = ['-id', 'username']
Or you could use the ordering in ModelAdmin:
class UserAdmin(admin.ModelAdmin):
ordering = ['-id', 'username']
# unregister user since its already been registered by auth
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Note: the ModelAdmin method will only change the ordering in the admin, it won't change the ordering of queries.
Paolo's answer is great; I wasn't previously aware of the new proxy support. The only issue with it is that you need to target your code to the OrderedUser model - which is in a sense similar to simply doing a User.objects.filter(....).order_by('username')
. In other words, it's less verbose but you need to explicitly write your code to target it. (Of course, as mentioned, you'd also have to be on trunk.)
My sense is that you want all User
queries to be ordered, including in third party apps that you don't control. In such a circumstance, monkeypatching the base class is relatively easy and very unlikely to cause any problems. In a central location (such as your settings.py), you could do:
from django.contrib.auth.models import User
User.Meta.ordering = ['username']