Python 许多关系不存在。它';它在不同的模式中
我将AbstractBaseUser与CustomPermissionsMixin一起使用。 CustomPermissionsMixin与django PermissionsMixin类似,不同之处在于我更改了用户权限和组的相关\u名称和相关\u查询\u名称,因此它不会与django PermissionsMixin相关\u名称冲突Python 许多关系不存在。它';它在不同的模式中,python,django,postgresql,django-models,django-rest-framework,Python,Django,Postgresql,Django Models,Django Rest Framework,我将AbstractBaseUser与CustomPermissionsMixin一起使用。 CustomPermissionsMixin与django PermissionsMixin类似,不同之处在于我更改了用户权限和组的相关\u名称和相关\u查询\u名称,因此它不会与django PermissionsMixin相关\u名称冲突 @python_2_unicode_compatible class CustomPermissionsMixin(models.Model): """
@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
....
我在两个不同的应用程序中使用相同的学生类。一个在App1中,另一个在App2中,字段略有不同。我使用postgresql。App1在模式public中,而App2在模式krt5jdjtrx中。(使用django租户模式。以编程方式创建)都使用AbstractBaseUser和CustomPermissionsMixin
class Student(AbstractBaseUser, CustomPermissionsMixin):
...
我还使用DRF Djangomodel权限
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.DjangoModelPermissions',
和自定义身份验证后端
class CustomBackend(ModelBackend):
....
问题在于django ModelBackend中的\u获取用户权限。假设user\u obj
类型为app1.Student
,user\u obj.user\u permissions.all()。query
有时使用app1\u Student\u user\u permissions
或app2\u Student\u user\u permissions
。为什么查询使用的是app2\u student\u user\u权限
,而user\u ob
j实际上是app1而不是app2。它将创建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 student与权限有很多关系,因此权限现在有app1关系和App2关系。我想它是由许多相关经理注册的。(权限将这两个关系视为公共架构)
如果我执行student1\u of_app1.user\u permissions.all(),Django将迭代权限所具有的关系。包括不存在的App2表。因此,它将创建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()
但是,有时没有错误,因为Django首先进入app1关系,但有时Django进入app2关系,因此会出现错误
如何防止这种情况发生?我发现问题在于django租户模式,而不是django。migrate_schema--shared实际上迁移了整个makemigration文件,而与共享的应用程序或租户无关。这两个应用程序(共享和租户)都在django\u content\u type
表中注册,该表也在auth\u permissions
中注册。因此,该关系不存在,因为此时尚未创建租户表,但许多租户关系已注册权限。可能它们都在同一个表中创建,Django看不到任何差异?我不太明白这会如何影响您,但您需要,但是组和用户权限冲突。这会影响权限检查,因为app2架构不在公共架构中。