首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django混合鸡肉和鸡蛋的噩梦

Django混合鸡肉和鸡蛋的噩梦
EN

Stack Overflow用户
提问于 2020-03-02 06:31:04
回答 1查看 88关注 0票数 0

我正在将一个基于Django的大型应用程序从Django 1.7应用程序升级到Django 2.2应用程序,并且在使用与权限相关的混入时遇到了很多问题。

代码语言:javascript
复制
   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抱怨)

我试图通过修改上面的代码来解决这个问题,创建一种不试图引用任何其他应用程序的“骨架”类,例如:

代码语言:javascript
复制
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,并通过下面的代码重写骨架类:

代码语言:javascript
复制
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类中,所有属性都存在。

我觉得我把自己挖进了一个更深的洞里,上面的方法是不可靠的,也永远不会正常工作。因此,任何帮助都将非常感谢!

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

edit:为了响应schillingt的评论,User类定义如下:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2020-03-02 16:00:23

作为循环引用的解决方案,django能够使用相关模型的字符串引用来指定ForeignKey (或任何其他关系字段),而不是导入实际的类。

代码语言:javascript
复制
user = models.ForeignKey('users.User', on_delete=models.CASCADE)

这是imo定义相关字段的推荐方式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60480397

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档