【发布时间】:2018-03-06 15:44:44
【问题描述】:
在 Django 模板中显示{{ user }} 时,默认行为是显示用户名,即user.username。
我将其更改为显示用户的姓名首字母,它们存储在单独的 (OneToOneField) UserProfile 模型中。
所以在customsignup/models.py 中,我已经成功地覆盖了__unicode__ 函数,得到了想要的结果:
# __unicode__-function overridden.
def show_userprofile_initials(self):
return self.userprofile.initials
User.__unicode__ = show_userprofile_initials
当然,数据库再次受到打击,因为每次要求user 对象显示为字符串时,它都需要独立选择UserProfile 模型。因此,即使这可行,它也会使数据库命中的数量增加不少。
所以我想做的是,每当从数据库调用User 模型时自动使用select_related('userprofile'),因为我首先在与用户打交道时基本上总是需要配置文件。
在更专业的术语中,我试图覆盖现有模型的模型管理器。所以我无法控制 User 模型定义本身,因为它在导入的库中。
所以我尝试以与覆盖__unicode__ 函数相同的方式覆盖User 模型的objects 成员,如下所示:
# A model manager for automatically selecting the related userprofile-table
# when selecting from user-table.
class UserManager(models.Manager):
def get_queryset(self):
# Testing indicates that code here will NOT run.
return super(UserManager, self).get_queryset().select_related('userprofile')
User.objects = UserManager()
这应该有效吗?如果是这样,我做错了什么?
(如果答案能表明这首先不应该起作用,我会将答案标记为正确。)
我在这里发现了一个类似的问题,但它是从另一端接近的: Automatically select related for OneToOne field
【问题讨论】:
-
为什么不只是
user.profile.initials?在您的配置文件模型上创建 OneToOne 字段还会为相关模型的实例创建反向访问器。您可以通过配置文件模型字段上的related_name关键字参数指定反向访问器名称。例如user = models.OneToOneField('auth.User', related_name='profile') -
我通常会避免在
__str__/__unicode__方法中使用外键。如果您总是想要显示首字母而不是用户名,这可能表明首字母应该是自定义User模型上的字段。即使您不这样做,如果您刚刚开始您的项目,创建自定义用户模型也是一个好主意。这样您就可以使用您的自定义管理器,而不是尝试修补默认的User模型。
标签: python django django-models