i am using django-admin, and i have a model as following. it shows as a dropdown list in the admin. how can i order it by alphabet? instead of default user ID?
user= models.ForeignKey(User)
i am using django-admin, and i have a model as following. it shows as a dropdown list in the admin. how can i order it by alphabet? instead of default user ID?
user= models.ForeignKey(User)
The problem you describe is, according to Django core devs, a feature, not a bug. In the beginning, Django ordered the User
field alphabetically, but this resulted in a performance issue for really big sites (namely Pownce at the time) with hundreds of thousands of users. But instead of asking the few huge Django websites to implement a workaround, the ordering was simply removed, and now every site that has models with a ForeignKey
to User
has a usability problem.
I posted an ugly workaround on the Django issue tracker about a year ago. Daniel Roseman posted a similar (and IMHO better) solution in another Stackoverflow question.
Why not at the level model?
class Meta:
ordering = ['field',]
Or at the level admin?
class Admin:
ordering = ('field',)
Create a custom form for your model and assign it to your ModelAdmin subclass -- you can override the ordering for the ModelChoiceField in the form's __init__
. For example:
# models.py
from django.db import models
from django.contrib.auth.models import User
class MyModel(models.Model):
user = models.ForeignKey(User)
# Other model fields ...
# forms.py
from django import forms
from django.contrib.auth.models import User
from myapp.models import MyModel
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
def __init__(self, *args, **kwargs):
super(MyModelForm, self).__init__(*args, **kwargs)
self.fields['user'].queryset = User.objects.order_by('first_name', 'last_name')
# admin.py
from django.contrib import admin
from myapp.models import MyModel
from myapp.forms import MyModelForm
class MyModelAdmin(admin.ModelAdmin):
form = MyModelForm
# Other admin attributes ...
admin.site.register(MyModel, MyModelForm)
If you have not only 5 but a decent amount of users, it might make sense to change the Admin to use raw_id_fields
for the user selection. That way, the users will be displayed in their own list view, allowing for filtering and sorting.
class MyAdmin(ModelAdmin):
raw_id_fields = ['user']
Actually, Django provides much better way of doing this. It's even in their documentation http://docs.djangoproject.com/en/1.2/topics/db/models/#proxy-models
You can easily sort in your admin.py
relevant Admin class.
Let's say your Admin class is the following:
@admin.register(UserStuff)
class UserStuffAdmin(admin.ModelAdmin):
list_display = ['user', 'other', 'fields']
ordering = ['user']
The line ordering = ['user']
will order by the user
field. Alphabetically or numerically, depending on the field. Uses the field's normal ordering method. You can also do ordering = ['-user']
which will sort in descending order.
Source: https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.ordering