アプリを再利用可能にし、カスタム ユーザー モデルと互換性を持たせようとしたところ、次の問題が発生しました。
User モデルが次のようなものだとしましょう:
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
(多対多は を定義しないことに注意してください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)