通过代理扩展 Django 用户模型可用的方法
Extending the methods available to the Django User model via a proxy
我正在集成一个应用程序,该应用程序过去有一个自定义用户模型来替换 auth.User
并向其他模型添加了自定义方法和关系。
我想让它更像是一个可重复使用的应用程序,所以我希望添加一个代理模型来为 User
提供相同的方法,以便 request.user.myfunc()
之类的东西仍然有效,并为额外字段创建与 User
的 OneToOneField
关系。
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
模型生成表,而 GoldBadge
和 SilverBadge
是代理模型,因此不会为它们生成 table。他们只是在扩展 Badge
模型的功能( 即 改变 Python 行为)。
请参阅 proxy models
上的文档
我正在集成一个应用程序,该应用程序过去有一个自定义用户模型来替换 auth.User
并向其他模型添加了自定义方法和关系。
我想让它更像是一个可重复使用的应用程序,所以我希望添加一个代理模型来为 User
提供相同的方法,以便 request.user.myfunc()
之类的东西仍然有效,并为额外字段创建与 User
的 OneToOneField
关系。
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
模型生成表,而 GoldBadge
和 SilverBadge
是代理模型,因此不会为它们生成 table。他们只是在扩展 Badge
模型的功能( 即 改变 Python 行为)。
请参阅 proxy models
上的文档