django admin sort foreign key field list

Sure - you can...

  • ModelAdmin specific ordering via formfield_for_foreignkey
  • Set default global ordering via a Manager
  • Set default ordering via model meta class
  • Form specific ordering then passed to your ModelAdmin

ModelAdmin specific method: (the other methods are in my answer in the post linked to above)

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "school":
            kwargs["queryset"] = School.objects.order_by('name')
        return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

Examples for the other 3 non admin specific methods in my post linked above.


It seems to work to add an admin class to the model admin, with the ordering equal to the field you want the drop down list sorted by.

# in the admin.py file

class SchoolAdmin(admin.ModelAdmin):
    ordering = ['school_name']

admin.site.register(SchoolModel, SchoolAdmin)

This works if you are willing to have an edit/add option next to drop down list.


You can override formfield_for_foreignkey() to change order as shown below:

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        formfield = super().formfield_for_foreignkey(db_field, request, **kwargs)
        if db_field.name == "school":            
            formfield.queryset = School.objects.order_by('name')
        return formfield

The approved answer might override other changes on the queryset, so I prefer to use this because it's safer:

class StudentAdmin(admin.ModelAdmin):
    def get_field_queryset(self, db, db_field, request):
        queryset = super().get_field_queryset(db, db_field, request)
        if db_field.name == 'school':
            queryset = queryset.order_by('name')
        return queryset