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

发布于 2024-08-06 14:25:23 字数 1337 浏览 6 评论 0原文

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

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。 。 。我如何告诉管理员按用户名对我的用户列表进行排序?谢谢!

I have an application that makes use of Django's UserProfile to extend the built-in Django User model. Looks a bit like:

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.

I have a similar class with:

class Meta:
    ordering = ['name']

That works great! But I don't "own" the User class, and when I try this trick in 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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

木緿 2024-08-13 14:25:23

class Meta:
    ordering = ['username']

应该如此

    ordering = ['user__username']

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

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

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.

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

情感失落者 2024-08-13 14:25:23

一种方法是定义一个自定义表单以用于管理员中的团队模型,并覆盖 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

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

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
家住魔仙堡 2024-08-13 14:25:23

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

User._meta.ordering=["username"]

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

User._meta.ordering=["username"]
仙女山的月亮 2024-08-13 14:25:23

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

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)

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:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文