【问题标题】:Django custom user model subclassed (by Zinnia)子类化的 Django 自定义用户模型(由 Zinnia 提供)
【发布时间】:2013-07-09 08:17:14
【问题描述】:

我已迁移到 Django 自定义用户模型 (CustomUser),其中几个其他模型具有外键和 M2M 关系。 CustomUser 也是 Zinnia 的作者模型 (Author) 的子类 - Zinnia 是一款出色的第三方博客应用。

我的问题是,当我通过关系(例如 OtherModel.customuser)访问 CustomUser 时,它会返回 CustomUser 的实例,但在我看来,当我访问 request.User 时,它是 Author 的实例。由于 Author 和 CustomUser 的属性是相同的,这通常没有太大区别,但是如果我想在我的视图中测试用户对象的等价性,我必须使用 request.user.id 而不是 request.user,我本能地不这样做'我不喜欢我正在处理的模型模棱两可。

也许我最好克服它并保持原样,因为在我的视图中进行了一些小的代码更改后一切正常。然而,在一个完美的世界里,我会一直提到相同的用户模型,但不确定如何最好地进步。有什么想法吗?

settings.py

AUTH_USER_MODEL = 'profiles.CustomUser'

models.py(在配置文件应用中)

class CustomUser(AbstractUser):

    visits = models.PositiveIntegerField(
        _('visits'),
        default=0,
        blank=True
    )

    def __unicode__(self):
        return self.username

class OtherModel(models.Model):

    author = models.ForeignKey(CustomUser)

我知道documentation 中的建议是与 settings.AUTH_USER_MODEL 建立关系,而不是直接与自定义用户模型建立关系。我打算改变这一点,但想在再次陷入迁移的痛苦之前了解我在做什么

author.py(在百日草应用中)

from django.contrib.auth import get_user_model


@python_2_unicode_compatible
class Author(get_user_model()):
    """
    Proxy model around :class:`django.contrib.auth.models.get_user_model`.
    """

    objects = get_user_model()._default_manager
    published = EntryRelatedPublishedManager()

在控制台中 get_user_model() 返回profiles.models.CustomUser 类

【问题讨论】:

  • 我也有同样的问题。你找到解决办法了吗?

标签: django zinnia


【解决方案1】:

我想我明白你的问题了。

默认情况下,Django 不会向下转换模型实例。举个例子:

from django.db import models

class Parent(models.Model):
    name = models.CharField()

class Child(Parent):
    pass

Parent(name="parent").save()
Child(name="child").save()

Parent.objects.all() # will return Parent instances
Child.objects.all() # will return Child instances

在您的情况下,您让 Zinnia 使用 Author 实例,而您的项目的其余部分使用 CustomUser 实例。所以基本上你可以对每个CustomUser 实例进行失望。您可以使用现有的 django 应用程序来实现这一点,例如 django-polymorphic(在我看来,这是使用具体继承时必须具备的)。但是,如果您的所有用户都不是作者,那您就完蛋了

您也可以妥协,并按如下方式实施手动向上转换:

from django.contrib.auth import get_user_model

class CustomUser(AbstractUser):

   # your logic...

    def as_custom_user(self):
        return super(get_user_model(), self)

用法:

assert request.user.as_custom_user() == article.author.as_custom_user()

【讨论】:

    猜你喜欢
    • 2013-07-28
    • 2016-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    • 2014-02-07
    相关资源
    最近更新 更多