检查多对多关系或属性

Posted

技术标签:

【中文标题】检查多对多关系或属性【英文标题】:Checking for many-to-many relation OR a property 【发布时间】:2020-10-23 14:02:39 【问题描述】:

如何检查是否存在多对多关系或是否满足其他属性?当我尝试查询时,它会返回一些行两次!

给定一个模型

from django.db import models
class Plug(models.Model):
    name = models.CharField(primary_key=True, max_length=99)

class Widget(models.Model):
    name = models.CharField(primary_key=True, max_length=99)
    shiny = models.BooleanField()
    compatible = models.ManyToManyField(Plug)

我的数据库中有以下项目:

from django.db.models import Q
schuko = Plug.objects.create(name='F')
uk = Plug.objects.create(name='G')
Widget.objects.create(name='microwave', shiny=True).compatible.set([uk])
Widget.objects.create(name='oven', shiny=False).compatible.set([uk])
Widget.objects.create(name='pc', shiny=True).compatible.set([uk, schuko])

现在我想要所有闪亮和/或与 Schuko 兼容的小部件名称:

shiny_or_schuko = sorted(
    Widget.objects.filter(Q(shiny=True) | Q(compatible=schuko))
    .values_list('name', flat=True))

但令我惊讶的是,这并没有返回['microwave', 'pc']。相反,'pc' 被列出了两次,即shiny_or_schuko['microwave', 'pc', 'pc']

这是一个 Django 错误吗?如果没有,我该如何设置只获得一次'pc' 的查询?

【问题讨论】:

【参考方案1】:

这是一个 Django 错误吗?

。您只需使用多对多表执行LEFT OUTER JOIN。如果两个或更多相关对象匹配,它将被包含多次。这可能是想要的行为,例如,如果您向从这些相关对象中获取值的元素添加额外的注释。

您可以使用.distinct() [Django-doc] 仅返回不同的 元素:

Widget.objects.filter(
    Q(shiny=True) | Q(compatible=schuko)
).values_list('name', flat=True).distinct()

【讨论】:

以上是关于检查多对多关系或属性的主要内容,如果未能解决你的问题,请参考以下文章

多对多关系核心数据

Laravel eloquent 检查不存在的多对多关系

CoreData 检查多对多关系是不是包含对象

从多对多关系的桥接表中检索数据的查询[关闭]

Laravel 多对多关系检查与中间表

核心数据:与状态的多对多关系