Stupid.Fat.Cat
Stupid.Fat.Cat

Reputation: 11295

django distinct query using custom equivalence

Say that my model looks like this:

class Alert(models.Model):
    datetime_alert = models.DateTimeField()
    alert_type = models.ForeignKey(Alert_Type, on_delete=models.CASCADE)
    dismissed = models.BooleanField(default=False)
    datetime_dismissed = models.DateTimeField(null=True)
    auid = models.CharField(max_length=64, unique=True)
    entities = models.ManyToManyField(to='Entity', through='Entity_To_Alert_Map')
    objects = Alert_Manager()

    def __eq__(self, other):
        return isinstance(other,
                          self.__class__) and self.alert_type == other.alert_type and \
               self.entities.all() == other.entities().all() and self.dismissed == other.dismissed

    def __ne__(self, other):
        return not self.__eq(other)

what I'm trying to accomplish is say this: two alert objects are equivalent if the dismissed status, alert type, and the associated entities are the same. Using this idea, is it possible to write a query to ask for all the distinct alerts based off that criteria? Selecting all of them and then filtering them out doesn't seem appealing.

Upvotes: 0

Views: 65

Answers (1)

Martin Hallén
Martin Hallén

Reputation: 1552

You mention one method to do it, and I don't think it is very bad. I'm not aware of anything in Django that can do this.

However, I want you to think why this problem arises? If two alerts are equal if message, status and type is the same, then maybe this should be it's own class. I would consider creating another class DistinctAlert (or some better name) and have a foreign key to this class from Alert. Or even better, have one class that is Alert, and one that is called AlertEvent(your Alert class).

Would this solve your problem?

Edit:

Actually, there is a way to do this. You can combine values() and distinct(). This way, your query will be

Alert.objects.all().values("alert_type", "dismissed", "entities").distinct()

This will return a dictionary.

See more in the documentation of values()

Upvotes: 2

Related Questions