【问题标题】:Get queryset of many-to-many field under another many-to-many field获取另一个多对多字段下的多对多字段查询集
【发布时间】:2018-11-04 08:14:17
【问题描述】:

我正在 django 中研究用户/角色/权限模型,其中模型结构是这样的。

class GlobalPermission(BasicAbstractClass):
    TYPE_CHOICES = ["user_level", "platform_level", "user_platform_access_level"]

    short_code = models.CharField(max_length=64, blank=True, null=True)
    name = models.CharField(max_length=92, blank=True, null=True)
    description = models.CharField(max_length=189, blank=True, null=True)
    type = EnumField(choices=TYPE_CHOICES, blank=True, null=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'global_permission'

class Role(BasicAbstractClass):
    ROLE_CHOICES = ["admin", "analyst", "moderator", "editor", "superuser", "developer"]
    SERVICE_CHOICES = ["social_media_management", "survey"]

    service = EnumField(choices=SERVICE_CHOICES)
    name = EnumField(choices=ROLE_CHOICES)
    permissions = models.ManyToManyField(GlobalPermission, related_name="role_permissions", blank=True, through="RolePermission")

    def __str__(self):
        return self.name + " of " + self.service

    class Meta:
        db_table = 'role'
class RolePermission(models.Model):
    role = models.ForeignKey(Role, on_delete=models.CASCADE)
    permission = models.ForeignKey(GlobalPermission, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.id)

    class Meta:
        db_table = "role_permissions"

class UserAccount(models.Model):
    roles = models.ManyToManyField(Role, related_name="+", blank=True, through="UserRole")

class UserRole(BasicAbstractClass):
    user = models.ForeignKey(UserAccount, on_delete=models.CASCADE)
    role = models.ForeignKey(Role, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.id)

    class Meta:
        db_table = "user_role"

我在这里想要的是获取用户的权限列表。在这里,用户可能被分配了多个角色,我想要一个包含这些角色的所有权限的查询集。

【问题讨论】:

  • related_name="+"?
  • 我不需要知道角色下的用户。所以我使用“+”作为相关名称禁用它

标签: django django-models django-queryset django-orm


【解决方案1】:

从你想要的 (GlobalPermission) 开始,然后在查询中向后工作:

GlobalPermission.objects.filter(role_permissions__user_accounts=target_user).distinct()

请注意,您需要一种在查询中引用UserAccount 的方法,例如:

class UserAccount(models.Model):
    roles = models.ManyToManyField(Role, blank=True, through="UserRole",
                                   related_name="+", related_query_name="user_accounts")

【讨论】:

    猜你喜欢
    • 2011-04-07
    • 2012-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多