Django管理界面:对于引用User的ForeignKey和ManyToManyField关系,如何排序

24

我有一个应用程序,利用Django的UserProfile来扩展内置的DjangoUser模型。看起来有点像:

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    # Local Stuff
    image_url_s = models.CharField(max_length=128, blank=True)
    image_url_m = models.CharField(max_length=128, blank=True)

    # Admin
    class Admin: pass

我已经向我的模型中添加了一个新类:

class Team(models.Model):
    name = models.CharField(max_length=128)
    manager = models.ForeignKey(User, related_name='manager')
    members = models.ManyToManyField(User, blank=True)

并且它已经在管理页面中注册:

class TeamAdmin(admin.ModelAdmin):
    list_display = ('name', 'manager')

admin.site.register(Team, TeamAdmin)

哎呀,在管理界面中,当我从下拉框中选择经理或通过多选字段设置团队成员时,它们是按用户数字ID排序的。我无论如何也无法弄清楚如何对它们进行排序。

我有一个类似的类:

class Meta:
    ordering = ['name']

这个方法很好用!但是我并不“拥有”User类,当我在UserAdmin中尝试使用时:

那就很困难了!

class Meta:
    ordering = ['username']

我得到了以下错误:

django.core.management.base.CommandError: 一个或多个模型未经验证: events.userprofile:“ordering”引用了一个不存在的字段“username”。

user.username 也不起作用。如果我想要指定像 image_url_s 一样的排序方式……那我该怎么告诉管理员按 username 对用户列表进行排序呢?谢谢!

4个回答

38

这个

class Meta:
    ordering = ['username']

应该是

    ordering = ['user__username']

如果它在您的UserProfile管理类中,那将停止异常,但我认为这并没有对您有所帮助。

按照您的描述对用户模型进行排序相当棘手,但请参见http://code.djangoproject.com/ticket/6089#comment:8以获得解决方案。


30

一种方法是在管理员中为您的团队模型定义自定义表单,并覆盖 manager 字段以使用具有正确排序的查询集:

<code>from django import forms

class TeamForm(forms.ModelForm):
    manager = forms.ModelChoiceField(queryset=User.objects.order_by('username'))

    class Meta:
        model = Team

class TeamAdmin(admin.ModelAdmin):
    list_display = ('name', 'manager')
    form = TeamForm
</code>

3
自 Django 1.8 版本开始,在 Class Meta 中也需要添加 fields = '__all__' - Flash

4
这可能存在风险,但是在你项目的models.py文件中,可以用一行代码来实现:
User._meta.ordering=["username"]

2

对于我来说,唯一有效的解决方案是使用代理模型。正如文档中所述,您可以为甚至内置的模型创建自己的代理模型,并像常规模型一样自定义任何内容:

class OrderedUser(User):
    class Meta:
        proxy = True
        ordering = ["username"]
    def __str__(self):
        return '%s %s' % (self.first_name, self.last_name)

之后,在您的模型中,只需将外键更改为:
user = models.OneToOneField(OrderedUser, unique=True)

甚至更加合适。
user = models.OneToOneField(OrderedUser, unique = True, parent_link = True)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接