使用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 和外键。
假设我有一个 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 asBlog.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 usedistinct()
就像您所做的那样,使用 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 和外键。