Say that I have a manytomany field, and say that I have x amount of elements.
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')
I am currently doing something
Distinct_Alert.objects.filter(alert_type=alert_type, entities__in=[entity[0] for entity in entities]).all()
but for some reasons, this query returns 2 distinct alerts with the same id, any idea why? If I add distinct() to it that solves the issue, but I'm trying to use get since the table should technically only have one entry matching that query.
I was initially doing this:
Distinct_Alert.objects.get_or_none(alert_type=alert_type, entities__in=[entity1, entity2....])
but then this bounced with an error, get_or_none is defined like so
class Utility_Manager(models.Manager):
def get_or_none(self, **kwargs):
try:
return self.get(**kwargs)
except self.model.DoesNotExist:
return None
but this won't work since I have 2 elements that are being returned, it would be an odd case if the elements were different and matching on the same query, but the rows that are returned are literally the same row.
When queries span multiple rows, duplicates should be expected.
From the 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()
So like you've done, using distinct
is the standard way for eliminating dups.