user2429940
user2429940

Reputation:

How to alphabetically order a drop-down list in Django admin?

Here's a (very) simplified version of my models:

laboratory/models.py

class Lab(Model):
    professor = ForeignKey('authors.Author')

authors/models.py

class Author(Model):
    name = CharField(max_length=100)

In the Django admin, when I add or update a Lab, a drop-down list containing each professors is automatically generated and displayed. The problem is this list is very long and it is not alphabetically ordered. I want the professor drop-down list to be alphabetically ordered by "name" field.

How can I do that?

Upvotes: 34

Views: 16470

Answers (4)

iperelivskiy
iperelivskiy

Reputation: 3581

You can define default ordering for Author model:

class Author(Model):
    name = CharField(max_length=100)

    class Meta:
        ordering = ('name',)

Keep in mind that this causes the objects in Django also to ordered and migration will have to be done.

You can do ordering = ['name'] under the AuthorAdmin file to order only for admin dashboard.

Upvotes: 28

aris
aris

Reputation: 24285

The current way to do this (January 2019):

In your admin.py file:

class AuthorAdmin(admin.ModelAdmin):
    ordering = ['name']

And then register it:

admin.site.register(Author, AuthorAdmin)

As described in the docs: https://docs.djangoproject.com/en/2.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.ordering

Upvotes: 9

ravi404
ravi404

Reputation: 7309

ModelAdmin specific ordering via formfield_for_foreignkey

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

Note IMHO its better not to set the ordering on model because the ordering of your admin page needs to be decoupled from the model.

Also all the queries fired on the model will use the order_by column, in which case you might have to index the ordering column with your other columns.

Upvotes: 30

Nafiul Islam
Nafiul Islam

Reputation: 82470

Well, you can use the ordering variable in django admin, or you could use order_with_respect_to underneath class Meta. So, first you need to add an admin.py file to the same directory as your models.py file. This is what your admin.py file should look like:

from django.contrib import admin

from models import Lab

class LabAdmin(admin.ModelAdmin):
    fields = ('name',)

    class Meta:
        ordering = ['name'] # ['-name'] if you want the opposite ordering


admin.site.register(Lab, LabAdmin)

Upvotes: -2

Related Questions