Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django admin sort foreign key field list

Is there an option in the django admin view for ordering of foreign key fields? i.e. I have a foreign key to a "School" model, which shows as a dropdown, sorted on pk-- I would like it to be sorted alphabetically.

like image 572
Colleen Avatar asked Jan 24 '12 19:01

Colleen


3 Answers

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.

like image 91
Yuji 'Tomita' Tomita Avatar answered Oct 14 '22 14:10

Yuji 'Tomita' Tomita


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.

like image 5
Kris O Avatar answered Oct 14 '22 15:10

Kris O


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
like image 3
Omar Natour Avatar answered Oct 14 '22 13:10

Omar Natour