Python 鸡和蛋的噩梦与Django mixin
我正在将一个基于Django的大型应用程序从Django 1.7升级到Django 2.2,并且在使用权限相关的mixin时遇到了很多问题Python 鸡和蛋的噩梦与Django mixin,python,django,mixins,Python,Django,Mixins,我正在将一个基于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 thi
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类,称为say 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的一些属性,例如,在我希望重新映射的PrincipalRoleRelation2类中,所有属性都存在
我觉得我正在把自己挖到一个越来越深的坑里,而上述方法是不可靠的,永远不会正常工作。因此,任何帮助都将不胜感激
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
编辑:针对schillingt的评论,用户类定义如下:
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)
这是定义相关字段的推荐方法 这似乎是一个循环引用问题,需要知道哪些应用程序依赖于哪些其他应用程序。你能告诉我们循环引用在哪里吗?嗨,schillingt,我在问题文本中包含了“用户”类的定义(包括隐晦的注释),其他类来自permissions/models.py。这在Django 1.7中确实有效。请注意,Django权限是一个非常古老的软件包,已经好几年没有更新了。这可能会很痛苦。你可能想先用Django 3.0更新这个项目,然后再回到你自己的项目。我确实做了,但我对Django还不是专家,不知道从哪里开始进行任何必要的更新。我更希望它能继续工作,或者至少以我能轻松找到和修复的明显方式失败。正如我所说,我的计划似乎几乎奏效了。只是我的替换mixin模块似乎没有替换“骨架”版本。也许有一种方法可以替代使用admin.site.register()?不幸的是,我没有这方面的经验,无法快速帮助您。也许其他人会/可以。我必须深入研究这个项目。