我将AbstractBaseUser与CustomPermissionsMixin一起使用。 CustomPermissionsMixin与django PermissionsMixin相同,区别在于我更改了user_permissions和groups的related_name和related_query_name,因此它不会与django PermissionsMixin related_name冲突
@python_2_unicode_compatible
class CustomPermissionsMixin(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 their groups.'
),
related_name="%(app_label)s_%(class)s_related",
related_query_name="%(app_label)s_%(class)ss",
)
user_permissions = models.ManyToManyField(
Permission,
verbose_name=_('student user permissions'),
blank=True,
help_text=_('Specific permissions for this user.'),
related_name="%(app_label)s_%(class)s_related",
related_query_name="%(app_label)s_%(class)ss",
)
class Meta:
abstract = True
....
我在两个不同的应用程序中拥有相同的Student类。一个在App1中,另一个在App2中,字段略有不同。我用postgresql。 App1处于架构公共状态,而App2处于架构krt5jdjtrx。(使用django tenant schema。以编程方式创建)两者都使用AbstractBaseUser和CustomPermissionsMixin
class Student(AbstractBaseUser, CustomPermissionsMixin):
...
我也使用DRF DjangoModelPermissions
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.DjangoModelPermissions',
自定义身份验证后端
class CustomBackend(ModelBackend):
....
问题发生在django ModelBackend内的_get_user_permissions
。假设user_obj
的类型为app1.Student
,user_obj.user_permissions.all().query
有时会使用app1_student_user_permissions
或app2_student_user_permissions
。为什么app2_student_user_permissions
j确实是app1而不是app2,查询如何使用user_ob
? 。它会创建django.db.utils.ProgrammingError:关系不存在。
def _get_user_permissions(self, user_obj):
print('inside _get_user_perm !!!!!!!!!!!!!!!!!!!!!!!')
print(user_obj)
print(type(user_obj))
print(user_obj.user_permissions.all().query)
return user_obj.user_permissions.all()
这是原始查询集
SELECT "auth_permission"."id", "auth_permission"."name", "auth_permission"."content_type_id", "auth_permission"."codename" FROM "auth_permission" INNER JOIN "app2_student_user_permissions" ON ("auth_permission"."id" = "app2_student_user_permissions"."permission_id") INNER JOIN "django_content_type" ON ("auth_permission"."content_type_id" = "django_content_type"."id") WHERE "app2_student_user_permissions"."student_id" = 1 ORDER BY "django_content_type"."app_label" ASC, "django_content_type"."model" ASC, "auth_permission"."codename" ASC
修改
App2学生的模式/表格将在稍后的程序中创建。 由于App2学生与权限有很多关系,因此权限现在具有app1关系和app2关系。我认为它是由ManyRelatedManager注册的。 (权限将这两种关系视为公共模式)
如果我执行student1_of_app1.user_permissions.all(),Django将迭代Permissions所具有的关系。包括不存在的App2表。因此它会创建django.db.utils.ProgrammingError:关系不存在。
然而,有时没有错误,因为Django首先进入app1关系,但有时Django进入app2关系,因此错误。
如何防止这种情况发生?