通过代理扩展 Django 用户模型可用的方法

Extending the methods available to the Django User model via a proxy

我正在集成一个应用程序,该应用程序过去有一个自定义用户模型来替换 auth.User 并向其他模型添加了自定义方法和关系。

我想让它更像是一个可重复使用的应用程序,所以我希望添加一个代理模型来为 User 提供相同的方法,以便 request.user.myfunc() 之类的东西仍然有效,并为额外字段创建与 UserOneToOneField 关系。

class ConsolesPermissionMixin(object):
    @property
    def is_admin(self):
        return self.is_superuser or self.is_staff

    _consoles = []

    @property
    def all_consoles(self):
        if not self._consoles:
            self._consoles = self.consoles.all()
        return self._consoles


class ProxyUser(ConsolesPermissionMixin, User):
    class Meta:
        proxy = True


class ConsoleUser(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL)
    participant = models.OneToOneField(
        'consoles.Participant',
        blank=True,
        null=True
    )
    consoles = models.ManyToManyField(
        'consoles.Console',
        null=True,
        blank=True,
    )
    objects = UserManager()

    class Meta:
        app_label = 'consoles'
        verbose_name = _('Console User')
        verbose_name_plural = _('Console Users')

因此,为了实现这一点,我在设置中设置了 AUTH_USER_MODEL = 'consoles.ProxyUser'。但这会导致 TypeError: ProxyUser cannot proxy the swapped model 'consoles.ProxyUser'.

当然要使用代理模型,它必须设置为AUTH_USER_MODEL,但是那是否意味着AUTH_USER_MODEL不能成为代理模型?

代理模型用于通过扩展模型 class 来修改模型的 Python 行为。数据库 table 不是为代理模型生成的。所以你不能为 AUTH_USER_MODEL 使用代理模型。事实上,如果您想要该模型的数据库 table,则不能使用代理模型。

要更好地理解代理模型,请考虑以下内容:

class Badge(models.Model):
    name = ...
    color = ... # gold/silver


class GoldBadge(Badge)
    class Meta:
        proxy = True

    def award(self, user):
        # award a gold badge to user

class SilverBadge(Badge):
    class Meta:
        proxy = True

    def award(self, user):
        # award a silver badge to user

仅为 Badge 模型生成表,而 GoldBadgeSilverBadge 是代理模型,因此不会为它们生成 table。他们只是在扩展 Badge 模型的功能( 改变 Python 行为)。

请参阅 proxy models

上的文档