Django自定义用户模型子类化(由Zinnia子类化)

5

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

我的问题是,当我通过关系访问CustomUser时,例如OtherModel.customuser,它返回CustomUser的实例,但在我的视图中访问request.User时,它是Author的实例。由于Author和CustomUser的属性完全相同,这一般没有太大的影响,但如果我想在我的Views中测试用户对象的等价性,我必须使用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)

我知道在文档中的建议是使用settings.AUTH_USER_MODEL来建立关系,而不是直接与自定义用户模型建立关系。但我计划更改它,但在重新启动迁移的痛苦之前,我想了解我正在做什么。

zinnia应用程序中的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 类。

1
我有同样的问题。你找到解决方法了吗? - Blaise
1个回答

0

我想我明白你的问题了。

默认情况下,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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接