我的模型在django.contrib.auth
中对内置用户模型有一个ForeignKey,我对管理员中的选择框总是按用户的主键排序而感到沮丧。
我更倾向于按字母顺序按用户名排序,虽然我本能地不想弄乱Django的内部,但我似乎无法找到一种更简单的方法来重新排序用户。
我能想到的最简单的方法是进入我的Django安装并添加
ordering = ('username',)
到用户模型的Meta类。
我是否可以使用某种monkeypatching或其他任何微创方式来修改User模型的排序?
或者,任何可以通过进行此更改而破坏的事情都可以吗?
答案 0 :(得分:23)
使用ModelAdmin objects指定自己的表单有一种方法。通过指定自己的表单,您可以完全控制表单的组成和验证。
假设FK为User
的模型为Foo
。
您的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到用户的模型提供此自定义表单定义,以便在管理站点中显示。
答案 1 :(得分:14)
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)
因此,每次创建表单时都会重新评估queryset,而不是在导入包含表单的模块时重新评估一次。