python - Django mixin 的鸡和蛋噩梦
问题描述
我正在将一个基于 Django 的大型应用程序从 Django 1.7 应用程序升级到 Django 2.2,并且在使用与权限相关的 mixin 时遇到了很多麻烦。
class PrincipalRoleRelation(models.Model):
"""A role given to a principal (user or group). If a content object is
given this is a local role, i.e. the principal has this role only for this
content object. Otherwise it is a global role, i.e. the principal has
this role generally.
user
A user instance. Either a user xor a group needs to be given.
group
A group instance. Either a user xor a group needs to be given.
role
The role which is given to the principal for content.
content
The content object which gets the local role (optional).
"""
:::
user = models.ForeignKey(User, verbose_name=_(u"User"), blank=True, null=True, on_delete=models.SET_NULL)
group = models.ForeignKey(Group, verbose_name=_(u"Group"), blank=True, null=True, on_delete=models.SET_NULL)
role = models.ForeignKey(Role, verbose_name=_(u"Role"), on_delete=models.CASCADE)
:::
但是,这在应用程序初始化期间无法加载,因为用户、组和角色等也是正在加载的应用程序,并且“populate() 不是可重入的”(所以 Dango 抱怨)
我试图通过修改上面的代码来创建一种不尝试引用任何其他应用程序的“骨架”类来解决这个问题,例如:
app_models_loaded = True
try:
from django.contrib.auth import get_user_model
User = get_user_model()
except:
app_models_loaded = False
if app_models_loaded:
from django.contrib.auth.models import Group
user = models.ForeignKey(User, verbose_name=_(u"User"), blank=True, null=True, on_delete=models.SET_NULL)
group = models.ForeignKey(Group, verbose_name=_(u"Group"), blank=True, null=True, on_delete=models.SET_NULL)
role = models.ForeignKey(Role, verbose_name=_(u"Role"), on_delete=models.CASCADE)
:::
然后在 manage.py 中定义完整的 mixin 类,称为 PrincipalRoleRelation2 并通过代码覆盖骨架类:
from django.contrib import admin
from permissions.models import PrincipalRoleRelation
if admin.site.is_registered(PrincipalRoleRelation):
admin.site.unregister(PrincipalRoleRelation)
admin.site.register(PrincipalRoleRelation, PrincipalRoleRelation2)
然而,尽管这似乎几乎可行,但我没有看到一些 PrincipalRoleRelation2 属性,例如“角色”,我希望它是重新映射的 PrincipalRoleRelation 类,其中存在所有属性。
我觉得我正在把自己挖到一个更深的洞里,上面的方法是不健全的,永远不会正常工作。所以任何帮助将不胜感激!
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
编辑:响应席林特的评论,用户类定义如下:
class User(AbstractBaseUser): # , PermissionsMixin):
""" Custom user model
Currently just used by the tests for django-permissions
All unique user fields required for a user
NB: Fields that are customizable across multiple identities will be part of a Profile object
"""
# Dont use PermissionsMixin since not using contrib.auth.models.Permissions
# and not using authentication backend perms ... so its only relevant for groups
# ... however it causes user.groups relations name clashes ..
# But we are using the groups part with django-permissions:
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.'),
related_name="user_set", related_query_name="user")
is_superuser = models.BooleanField(_('superuser status'), default=False,
help_text=_('Designates that this user has all permissions without '
'explicitly assigning them.'))
username = models.EmailField(_('Email (Username)'), max_length=255, unique=True)
# Make username an email and just dummy in email here so its clearer for user.email use cases
解决方案
作为循环引用的解决方案,django 能够通过字符串引用指定 ForeignKey(或任何其他关系字段)到相关模型,而不是导入实际类。
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
这是 imo 推荐的定义相关字段的方法。
推荐阅读
- node.js - 如何设置自定义 firefox 二进制路径 node.js 和 selenium?
- c - 如何将库放在 ARM 微控制器上的不同内存位置?
- r - 从R中的alphahull中提取多个多边形
- symfony - Symfony 5.0.8 运行服务器后无限加载
- javascript - 在 Elementor / Wordpress 中永久更新 html 元素
- firebase - 如何在没有大量加载时间的情况下使用由云功能提供的 Nuxt.js?
- mysql - 将变量传递给 SQL 查询 LIMIT sql Pandas
- jpa - 实体集合在数据库更改后未更新
- delphi - 在 Firemonkey 中将图像添加到 TTabItem
- ios - withSessionContinueSeconds 方法在 Flurry 中不起作用