12

我有一个模型,其中有一个 ForeignKey 到内置用户模型,django.contrib.auth我对管理员中的选择框总是按用户的主键排序这一事实感到沮丧。

我宁愿让它按用户名的字母顺序排序,虽然我的本能不想摆弄 Django 的内部,但我似乎找不到更简单的方法来重新排序用户。

我能想到的最直接的方法是进入我的 Django 安装并添加

ordering = ('username',)

到 User 模型的 Meta 类。

是否有某种我可以做的猴子补丁或任何其他侵入性较小的方式来修改用户模型的顺序?

或者,任何人都可以通过做出这种改变来破坏任何东西吗?

4

2 回答 2

23

有一种方法可以使用ModelAdmin 对象来指定您自己的表单。通过指定您自己的表单,您可以完全控制表单的组成和验证。

假设具有 FK 的模型UserFoo

myapp/models.py可能看起来像这样:

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

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

然后,您将创建一个myapp/admin.py包含以下内容的文件:

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)

完成此操作后,<select>下拉列表将根据用户名对用户对象进行排序。无需担心Foo...上的其他字段,您只需要在FooAdminForm类中指定覆盖。不幸的是,您需要为每个模型提供此自定义表单定义,该模型具有您希望在管理站点中显示的用户的 FK。

于 2009-05-29T01:31:26.563 回答
15

Jarret 上面的回答实际上应该是:

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)

因此,每次创建表单时都会重新评估查询集,而不是在导入包含表单的模块时重新评估一次。

于 2009-07-21T10:52:50.663 回答