【问题标题】:Model field for implicit many-to-many (many-to-many-to-many) relationship in DjangoDjango中隐式多对多(多对多对多)关系的模型字段
【发布时间】:2020-07-01 20:21:15
【问题描述】:

假设在我的 django 应用模型中,我有三个模型,每个模型都有多对多关系(这是一个玩具示例)。

class User(models.Model):

    permissions_group = models.ManyToManyField(Group)

class Group(models.Model):

    permissions_area = models.ManyToManyField(Area)

class Area(models.Model):
    #other irrelevant field data...
    pass

我想在我的User 模型上有一个字段,它表达了用户和区域之间的关系,这是一个隐含的多对多模型(也就是说我没有定义创建的附加关系数据库中的其他表,我使用通过组的关系。

我曾考虑使用自定义管理器,但这似乎不允许使用标准相关字段管理器看到的那种关系过滤;我可以简单地在类上设置一个装饰属性:

class User(models.Model):

    @property
    permissions_areas(self):
        return Area.objects.filter(group__in=self.permissions_groups.all())

但这看起来很笨拙,并且不使用任何 django 约定。有没有一种传统的方法可以在 Django 中使用我缺少的 Django 工具(自定义管理器或类似于 RelatedManager 的工具)来执行此操作?

【问题讨论】:

  • 你的解决方案绝对OK。

标签: python django


【解决方案1】:

您可以只使用两个下划线来查看关系,因此:

class User(models.Model):

    @property
    permissions_areas(self):
        return Area.objects.filter(group__user=self).distinct()

如果User 可以属于有权访问该区域的多个 组,则.distinct() 很有用。如果没有.distinct(),它将为有权访问该区域和用户所属的每个组返回Area

【讨论】:

  • 这绝对比我的构造更整洁,但是如果我能避免的话,使用@property 装饰器并不是我想要采取的路线(更喜欢RelatedManager 类之类的东西跨度>
  • 请注意,在此答案中(以及您的示例中),user.permissions_areas 为您提供了一个查询集,因此您可以过滤()、删除()、更新()等。例如 user.permissions_areas.filter(some_field__contains='x') .它不是一个 RelatedManager 界面,但仍然非常通用。
猜你喜欢
  • 2019-05-09
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
  • 2012-07-22
  • 2015-02-03
  • 2012-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多