Hi,
You can use Django annotation feature which will add a field to your
queryset objects and that field can behve like any real field


On Thu, Jun 6, 2019 at 8:22 PM Chetan Ganji <[email protected]> wrote:

> Yes Olivier, You are right :P
>
> If I understand the problem correctly this time, you want the field
> available on django model, but does not want the python to do the
> calculation.
> You want the database to compute the value.
>
> If yes, you could use a row level trigger i.e after create and after
> update trigger. PostgreSQL supports it.
>
>
> class Sales(models.Model):
> buying_price = models.FloatField()
> selling_price = models.FloatField()
> profit = models.models.FloatField(null=True, blank=True)
>
>
> *For your reference - *
> *RE: SQL Triggers*
> http://www.postgresqltutorial.com/introduction-postgresql-trigger/
>
> *RE: database-side computed fields*
> Instead of concatenation as in the below example, you would do some other
> operation and/or aggregation which would be calculated by the database.
>
> https://dba.stackexchange.com/questions/21897/set-a-columns-default-value-to-the-concatenation-of-two-other-columns-values
>
>
> If it works, as it would be on database level, you have to document it in
> the readme file of your project.
> Otherwise, next developer on the project might not know about the trigger
> and bang his head on the floor like I did earlier, lolz :P
>
> I hope it helps this time :P
>
>
> Regards,
> Chetan Ganji
> +91-900-483-4183
> [email protected]
> http://ryucoder.in
>
>
> On Thu, Jun 6, 2019 at 6:57 PM Olivier Dalang <[email protected]>
> wrote:
>
>> Thanks Chetan for trying to help, but please read carefully the issue, as
>> you didn't understand what I'm trying to do.
>>
>> In the meantime, and for the record, I found this, which works for simple
>> cases.  https://github.com/schinckel/django-computed-field
>>
>> On Thu, 6 Jun 2019 at 14:57, Chetan Ganji <[email protected]> wrote:
>>
>>> I think this would solve your problem. Whatever calculations needs to be
>>> done, you can do it manually before saving the Sales instance.
>>> Preferably after checking if form.is_valid() in case of django and in
>>> the function perform_create() in case of django rest framework.
>>>
>>>
>>> class Sales(models.Model):
>>> buying_price = models.FloatField()
>>> selling_price = models.FloatField()
>>> profit = models.models.FloatField()
>>>
>>>
>>> Cheers!
>>>
>>>
>>> Regards,
>>> Chetan Ganji
>>> +91-900-483-4183
>>> [email protected]
>>> http://ryucoder.in
>>>
>>>
>>> On Thu, Jun 6, 2019 at 4:50 PM Olivier Dalang <[email protected]>
>>> wrote:
>>>
>>>> Thanks for the answer. As said, the @property + python method wouldn't
>>>> work for my use case, as I need to be able to use the field in the queryset
>>>> to filter/order (plus my actual computed field use aggregates expressions).
>>>>
>>>> Cheers,
>>>>
>>>> Olivier
>>>>
>>>> On Thu, 6 Jun 2019 at 12:36, Chetan Ganji <[email protected]>
>>>> wrote:
>>>>
>>>>> I had a similar need in one of my clients project, I ended up using
>>>>> @property and a python method.
>>>>>
>>>>> AFAIK, AnnotationField is absent from django models. If you would like
>>>>> to write one, below is the material you need to refer.
>>>>> https://docs.djangoproject.com/en/2.2/howto/custom-model-fields/
>>>>>
>>>>>
>>>>> Regards,
>>>>> Chetan Ganji
>>>>> +91-900-483-4183
>>>>> [email protected]
>>>>> http://ryucoder.in
>>>>>
>>>>>
>>>>> On Thu, Jun 6, 2019 at 3:36 PM Olivier Dalang <
>>>>> [email protected]> wrote:
>>>>>
>>>>>> 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 [email protected].
>>>>>> To post to this group, send email to [email protected].
>>>>>> 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
>>>>>> <https://groups.google.com/d/msgid/django-users/CAExk7p3eXvCUCxB3LgZJHTrVXzLuD%3DNqUE79a-dqtUXzekXgJg%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>>> .
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>> --
>>>>> 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 [email protected].
>>>>> To post to this group, send email to [email protected].
>>>>> 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/CAMKMUjscehKiqt4Gcu3Cnm%2BHKhH8Y98RnGhR6chVZ7NS5qc-sw%40mail.gmail.com
>>>>> <https://groups.google.com/d/msgid/django-users/CAMKMUjscehKiqt4Gcu3Cnm%2BHKhH8Y98RnGhR6chVZ7NS5qc-sw%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>> --
>>>> 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 [email protected].
>>>> To post to this group, send email to [email protected].
>>>> 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/CAExk7p1PBMC7rR4iBu_80pwTBoie4NydB9gk0jKAqOqNwCGhZQ%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/django-users/CAExk7p1PBMC7rR4iBu_80pwTBoie4NydB9gk0jKAqOqNwCGhZQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>> --
>>> 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 [email protected].
>>> To post to this group, send email to [email protected].
>>> 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/CAMKMUjtqs1a9t7XKoDQcPxZm1CrC7eqyD7jCZSDG12-KKyd0HA%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/django-users/CAMKMUjtqs1a9t7XKoDQcPxZm1CrC7eqyD7jCZSDG12-KKyd0HA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
>> 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 [email protected].
>> To post to this group, send email to [email protected].
>> 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/CAExk7p1ddVqskXV%3DKQXtri5cLTwJutzFeZDz5aeDanVGTcKHtQ%40mail.gmail.com
>> <https://groups.google.com/d/msgid/django-users/CAExk7p1ddVqskXV%3DKQXtri5cLTwJutzFeZDz5aeDanVGTcKHtQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
> --
> 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 [email protected].
> To post to this group, send email to [email protected].
> 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/CAMKMUjsi5JE2jSp5_p_LyHm5V1P%3DBHyH6V%2BCN37HsEoK3sr5gw%40mail.gmail.com
> <https://groups.google.com/d/msgid/django-users/CAMKMUjsi5JE2jSp5_p_LyHm5V1P%3DBHyH6V%2BCN37HsEoK3sr5gw%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 [email protected].
To post to this group, send email to [email protected].
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/CALZ%3DbELw4J%3DsY-5Aa5aUDL1_XMKZYtMpR-iJZhrxVZa-7Ak8vA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to