gpt4 book ai didi

python - 多对多关系不存在。它在不同的模式中

转载 作者:太空狗 更新时间:2023-10-30 01:20:31 24 4
gpt4 key购买 nike

我将 AbstractBaseUser 与 CustomPermissionsMixin 一起使用。CustomPermissionsMixin 与 django PermissionsMixin 有点相同,不同之处在于我为 user_permissions 和组更改了 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 在模式 public 中,而 App2 在模式 krt5jdjtrx 中。(使用 django 租户模式。以编程方式创建)两者都使用 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_objapp1.Student 类型,user_obj.user_permissions.all().query 有时使用 app1_student_user_permissions 或者app2_student_user_permissions。为什么查询使用 app2_student_user_permissionsuser_obj 确实是 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 与 Permissions 具有多对多关系,因此 Permissions 现在具有 app1 关系和 app2 关系。我认为它是由 ManyRelatedManager 注册的。 (权限将这两个关系视为公共(public)模式)

如果我执行 student1_of_app1.user_permissions.all(),Django 将遍历 Permissions 具有的关系。包括不存在的 App2 表。因此它将创建 django.db.utils.ProgrammingError:关系不存在。

但是,有时没有错误,因为 Django 先进入 app1 关系,但有时 Django 进入 app2 关系,因此出错。

如何防止这种情况发生?

最佳答案

我发现问题出在 Django 租户架构上,而不是 Django。 migrate_schema --shared 实际上会迁移整个 makemigration 文件,而不管应用程序是共享的还是租户的。 这两个应用程序(共享的和租户的)都在 django_content_type 表中注册,该表也在授权权限。因此,该关系不存在,因为此时尚未创建租户表,但已为权限注册了 manytomany 关系。

关于python - 多对多关系不存在。它在不同的模式中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38821937/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com