python Django Admin:引用用户的 ForeignKey 和 ManyToManyField 关系的排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1474135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:21:19  来源:igfitidea点击:

Django Admin: Ordering of ForeignKey and ManyToManyField relations referencing User

pythondjangosortingadminuser-profile

提问by dannyman

I have an application that makes use of Django's UserProfileto extend the built-in Django Usermodel. Looks a bit like:

我有一个使用 DjangoUserProfile扩展内置 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

I have added a new class to my model:

我在我的模型中添加了一个新类:

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

And it is registered into the Admin:

它被注册到管理员中:

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

admin.site.register(Team, TeamAdmin)

Alas, in the admin inteface, when I go to select a manager from the drop-down box, or set team members via the multi-select field, they are ordered by the User numeric ID. For the life of me, I can not figure out how to get these sorted.

唉,在管理界面中,当我从下拉框中选择经理或通过多选字段设置团队成员时,他们按用户数字 ID 排序。对于我的生活,我无法弄清楚如何对这些进行排序。

I have a similar class with:

我有一个类似的课程:

class Meta:
    ordering = ['name']

That works great! But I don't "own" the Userclass, and when I try this trick in UserAdmin:

效果很好!但我不“拥有”这个User班级,当我尝试这个技巧时UserAdmin

class Meta:
    ordering = ['username']

I get:

我得到:

django.core.management.base.CommandError: One or more models did not validate:events.userprofile: "ordering" refers to "username", a field that doesn't exist.

django.core.management.base.CommandError: One or more models did not validate:events.userprofile: "ordering" refers to "username", a field that doesn't exist.

user.usernamedoesn't work either. I could specify, like image_url_sif I wanted to . . . how can I tell the admin to sort my lists of users by username? Thanks!

user.username也不起作用。我可以指定,就像image_url_s我想要的那样。. . 我如何告诉管理员按以下方式对我的用户列表进行排序username?谢谢!

回答by Greg

This

class Meta:
    ordering = ['username']

should be

应该

    ordering = ['user__username']

if it's in your UserProfile admin class. That'll stop the exception, but I don't think it helps you.

如果它在您的 UserProfile 管理类中。这会阻止异常,但我认为它对你没有帮助。

Ordering the User model as you describe is quite tricky, but see http://code.djangoproject.com/ticket/6089#comment:8for a solution.

按照您的描述订购 User 模型非常棘手,但请参阅http://code.djangoproject.com/ticket/6089#comment:8以获取解决方案。

回答by Daniel Roseman

One way would be to define a custom form to use for your Team model in the admin, and override the managerfield to use a queryset with the correct ordering:

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

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

回答by sam

This might be dangerous for some reason, but this can be done in one line in your project's models.pyfile:

由于某种原因,这可能很危险,但这可以在项目models.py文件的一行中完成:

User._meta.ordering=["username"]

回答by JohnyGomez

For me, the only working solution was to use Proxy Model. As stated in the documentation, you can create own proxy models for even built-in models and customize anything like in regular models:

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

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

After that, in your model just change Foreign Key to:

之后,在您的模型中只需将外键更改为:

user = models.OneToOneField(OrderedUser, unique=True)

or even more suitable

甚至更合适

user = models.OneToOneField(OrderedUser, unique = True, parent_link = True)