Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reorder users in django auth

I have a model that has a ForeignKey to the built-in user model in django.contrib.auth and I'm frustrated by the fact the select box in the admin always sorts by the user's primary key.

I'd much rather have it sort by username alphabetically, and while it's my instinct not to want to fiddle with the innards of Django, I can't seem to find a simpler way to reorder the users.

The most straightforward way I can think of would be to dip into my Django install and add

ordering = ('username',)

to the Meta class of the User model.

Is there some kind of monkeypatching that I could do or any other less invasive way to modify the ordering of the User model?

Alternatively, can anyone thing of anything that could break by making this change?

like image 612
banterability Avatar asked May 28 '09 23:05

banterability


2 Answers

Jarret's answer above should actually read:

from django.contrib.auth.models import User
from django.contrib import admin
from django import forms
from yourapp.models import Foo

class FooAdminForm(forms.ModelForm):
    class Meta:
        model = Foo

    def __init__(self, *args, **kwds):
        super(FooAdminForm, self).__init__(*args, **kwds)
        self.fields['user'].queryset = User.objects.order_by(...)

class FooAdmin(admin.ModelAdmin):
    # other stuff here
    form = FooAdminForm

admin.site.register(Foo, FooAdmin)

so the queryset gets re-evaluated each time you create the form, as opposed to once, when the module containing the form is imported.

like image 149
elo80ka Avatar answered Oct 14 '22 08:10

elo80ka


There is a way using ModelAdmin objects to specify your own form. By specifying your own form, you have complete control over the form's composition and validation.

Say that the model which has an FK to User is Foo.

Your myapp/models.py might look like this:

from django.db import models
from django.contrib.auth.models import User

class Foo(models.Model):
    user = models.ForeignKey(User)
    some_val = models.IntegerField()

You would then create a myapp/admin.py file containing something like this:

from django.contrib.auth.models import User
from django import forms
from django.contrib import admin

class FooAdminForm(forms.ModelForm):
    user = forms.ModelChoiceField(queryset=User.objects.order_by('username'))

    class Meta:
        model = Foo

 class FooAdmin(admin.ModelAdmin):
     form = FooAdminForm

 admin.site.register(Foo, FooAdmin)

Once you've done this, the <select> dropdown will order the user objects according to username. No need to worry about to other fields on Foo... you only need to specify the overrides in your FooAdminForm class. Unfortunately, you'll need to provide this custom form definition for every model having an FK to User that you wish to present in the admin site.

like image 28
Jarret Hardie Avatar answered Oct 14 '22 08:10

Jarret Hardie