使用django中的对象列表查询manytomany字段返回具有相同ID的多行

Querying manytomany field using a list of objects in django returning multiple rows with same id

假设我有一个 manytomany 字段,并说我有 x 个元素。

class Distinct_Alert(models.Model):
    alert_type = models.ForeignKey(Alert_Type, on_delete=models.CASCADE)
    entities = models.ManyToManyField(to='Entity', through='Entity_To_Alert_Map')
    objects = Utility_Manager()

class Entity(models.Model):
    label = models.CharField(max_length=255, blank=False)
    entity_type = models.ForeignKey(Entity_Type_Label)
    related_entities = models.ManyToManyField('self')
    identical_entities = models.ManyToManyField('self')
    objects = Entity_Manager()

    class Meta:
        unique_together = ('label', 'entity_type')

我目前正在做某事

Distinct_Alert.objects.filter(alert_type=alert_type, entities__in=[entity[0] for entity in entities]).all()

但由于某些原因,此查询 returns 2 个具有相同 ID 的不同警报,知道为什么吗?如果我向它添加 distinct() 来解决问题,但我正在尝试使用 get,因为 table 在技术上应该只有一个条目匹配该查询。

我最初是这样做的:

Distinct_Alert.objects.get_or_none(alert_type=alert_type, entities__in=[entity1, entity2....])

但随后出现错误,get_or_none 定义如下

class Utility_Manager(models.Manager):
    def get_or_none(self, **kwargs):
        try:
            return self.get(**kwargs)
        except self.model.DoesNotExist:
            return None

但这行不通,因为我有 2 个要返回的元素,如果元素不同并且在同一查询中匹配,那将是一个奇怪的情况,但返回的行实际上是同一行.

当查询跨越多行时,应该会出现重复。

来自docs

By default, a QuerySet will not eliminate duplicate rows. In practice, this is rarely a problem, because simple queries such as Blog.objects.all() don’t introduce the possibility of duplicate result rows. However, if your query spans multiple tables, it’s possible to get duplicate results when a QuerySet is evaluated. That’s when you’d use distinct()

就像您所做的那样,使用 distinct 是消除重复项的标准方法。

看看 def prefetch_related(self, *lookups): """ Returns 将预取指定的新 QuerySet 实例 QuerySet 时的多对一和多对多相关对象 已评价。

当 prefetch_related() 被多次调用时,查找列表 预取附加到。如果调用 prefetch_related(None),列表 被清除。 要么 def select_related(self, *fields): """ Returns 一个新的 QuerySet 实例,它将 select 相关对象。

如果指定字段,则必须是外键字段,并且只能是那些 相关对象包含在 selection.

我在 views.py 的 select 查询中使用了它们,并且非常适合使用 manytomany 和外键。