试图使我的应用程序可重用并与自定义用户模型兼容,我遇到了以下问题:
假设用户模型如下:
class Member(AbstractUser):
pass # basically the builtin User with another name
由于此代码来自django.contrib.auth.models
:
class PermissionsMixin(models.Model):
"""
A mixin class that adds the fields and methods necessary to support
Django's Group and Permission model using the ModelBackend.
"""
is_superuser = models.BooleanField(_('superuser status'), default=False,
help_text=_('Designates that this user has all permissions without '
'explicitly assigning them.'))
groups = models.ManyToManyField(Group, verbose_name=_('groups'),
blank=True, help_text=_('The groups this user belongs to. A user will '
'get all permissions granted to each of '
'his/her group.'))
user_permissions = models.ManyToManyField(Permission,
verbose_name=_('user permissions'), blank=True,
help_text='Specific permissions for this user.')
class AbstractUser(AbstractBaseUser, PermissionsMixin): # <- included there
....
(请注意,多对多groups
没有定义 a related_name
。)
现在,在与小组合作时,我不能这样做:
group.user_set.add(...)
因为反向RelatedManager
名称实际上是member_set
.
请注意,Member
在这种情况下模型的名称是,但它可以是任何其他名称。
现在,我正在执行以下操作:
getattr(group, "%s_set" % settings.AUTH_USER_MODEL.split('.')[-1].lower())
是的,很丑。
问题:对此有任何常见或固定的解决方案吗?
编辑我的最终实现:
@classmethod
def _get_user_reverse_field_name(cls):
User = get_user_model()
cls._user_reverse_field_name = User._meta.get_field('groups').related.get_accessor_name()
@property
def members(self):
if not hasattr(self, '_user_reverse_field_name'):
self._get_user_reverse_field_name()
return getattr(self, self._user_reverse_field_name)