Thursday, June 6, 2019

Annotations as models fields

Dear list,

I was wondering whether there's a package or pattern to define annotations as model fields, so that they could really be used as database-side computed fields.

Currently, I do something like this (not tested, it's a simplified case):

class SalesManager(models.Manager):
def get_queryset(self):
return super().get_queryset().annotate(
profit=F("selling_price")-F("buying_price")
)

class Sales(models.Model):
objects = SalesManager()

buying_price = models.FloatField()
selling_price = models.FloatField()
...

Ideally, I'd see something like :

class Sales(models.Model):
buying_price = models.FloatField()
selling_price = models.FloatField()
profit = models.AnnotationField(F("selling_price")-F("buying_price"))
...

An AnnotationField would behave like a read-only field, excepted that it wouldn't have a database column.

This would have the following benefits :
- much less verbose
- all instance related stuff in one place
- it would make it possible to refer to "profit" as a model field
    - you could use the field in Meta.ordering
    - you could easily display in django.admin without additional methods

Of course similar result can be achieved with @property and a python method, but I really need this to be on the database side to use subqueries, sorting and filtering, etc.  

Does anything like this exist ? Is it possible to emulate this behaviour somehow ?

Thanks !!

Olivier


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAExk7p3eXvCUCxB3LgZJHTrVXzLuD%3DNqUE79a-dqtUXzekXgJg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment