【问题标题】:How to change User representation in Django Admin when used as Foreign Key?用作外键时如何更改 Django Admin 中的用户表示?
【发布时间】:2016-10-31 08:56:46
【问题描述】:

我有几个模型将用户作为外键。用户列表显示用户名,但我想自定义它。我是否必须使用自定义模型扩展 User 模型并编写自己的 __str__ 函数?有没有更简单的方法? 我认为您不能使用可调用的字段集,对吧?

【问题讨论】:

  • 您可以使用自定义用户管理员,例如@dmitryro。你不需要 django-admin-tools 来完成你所要求的。如果您还需要在其他地方显示用户名以外的其他内容,我建议使用代理模型并覆盖 str 方法,而不是创建自定义用户模型。
  • 我可以为用户创建一个代理模型,但我想我必须将它用作所有模型的外键?
  • 是的,你必须这样做。
  • 我覆盖了 User str 函数 User.add_to_class("__str__", get_user_email),该函数在管理员 ListView 中有效,但在查看/添加单个项目时无效。
  • 覆盖__unicode__工作

标签: python django django-admin


【解决方案1】:

我觉得__unicode__()方法不对,你应该使用__str__()方法。

对于Python 2.x__str__() 方法将返回 str(bytes),__unicode__() 方法将返回 unicode (text)。

print语句和str内置调用__str__()确定 对象的人类可读表示。内置的 unicode 如果存在则调用__unicode__(),否则回退到 __str__() 并使用系统编码对结果进行解码。相反,Model 基类自动派生自 __str__() __unicode__() 通过编码为 UTF-8。 read here complete

但是在Python 3.x 中只有__str__(),没有__unicode__() 方法。

Django 提供了一种简单的方法来定义__str__()__unicode__() 适用于 Python 2 和 3 的方法:您必须定义一个 __str__() 方法返回文本并应用python_2_unicode_compatible() 装饰器。

在 Python 3 上,装饰器是无操作的。在 Python 2 上,它定义了 适当的 __unicode__()__str__() 方法(替换 原__str__()方法在处理中)。

这是来自 django 文档的示例。

from django.utils.encoding import python_2_unicode_compatible

@python_2_unicode_compatible
class MyClass(object):
    def __str__(self):
        return "Instance of my class"

解决方案: 以与上面为您的班级和 在models.py 中,添加一个方法,该方法将被添加到用户模型中。

from django.contrib.auth.models import User

def get_name(self):
    return '{} {}'.format(self.first_name, self.last_name)

User.add_to_class("__str__", get_name)

【讨论】:

  • Django 基 User 类具有该装饰器,因此,在加载时 __unicode__ 设置为 __str__'. Therefore, it looks like we would need to override __unicode__`
  • 其实不需要重写__unicode__方法,为了防止重写我们使用的是add_to_class
【解决方案2】:

ForeignKeys 在 Django 表单中由 ModelChoiceFields 表示。 ModelChoiceField 类有一个 label_from_instance 方法,它决定如何呈现选择。因此,为了在 Admin 中更改此表示,您需要修改此表单字段。

这是一个简单的例子。

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        field = super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
        if db_field.name == "user":
            field.label_from_instance = lambda u: "My Object #%i" % u.id
        return field

【讨论】:

  • 这是一个很好的解决方案,但需要为每个模型定义一个自定义管理模型。
  • 很好,因为有时您只想在外键下拉列表中更改模型的字符串表示形式
【解决方案3】:

假设你有这样的模型

class UserProfile(models.Model):
    user = models.OneToOneField(User, unique=True, verbose_name=_('user'), related_name='profile')
    city = models.CharField(max_length=128, null=True, blank=True)

如果您想在管理页面中显示用户的电子邮件而不是用户名或用户 ID,那么您可以这样做

class UserProfileAdmin(admin.ModelAdmin):
    list_display = ('get_user', 'city')

    def get_user(self, obj):
        return obj.user.email
    get_user.short_description = 'User'
    get_user.admin_order_field = 'user__id'

【讨论】:

  • 问题是询问当用户是外键时用户字段在其​​他对象上的外观。这只会更改 UserProfile 页面上的表示。
【解决方案4】:

您可以通过覆盖 User __unicode__ 方法来更改 Django 默认用户的字符串表示形式。在您的应用程序中的某处添加以下代码,可能在 models.py 中

def custom_user_display(self):
    return self.email + ', ' self.first_name # write your representation here

User.add_to_class("__unicode__", custom_user_display) # override the __unicode__ method

【讨论】:

    猜你喜欢
    • 2011-03-05
    • 2021-06-13
    • 2016-11-12
    • 2012-07-05
    • 2018-09-19
    • 2018-10-27
    • 2011-04-25
    • 2016-06-06
    • 1970-01-01
    相关资源
    最近更新 更多