I disagree with not being able to calculate it locally (without the database): such a calculation depends on other fields. What if a dependent field is updated, but the object is not yet saved. What should the value be?

>>> c.age, c.is_adult
17, False
>>> c.age = 40
>>> c.age, c.is_adult
40, False

Would not make sense to me.

As a first step, maybe it would make sense to make it easier to support custom filter attribute. Right now you have to create a custom query set subclass implementing .filter where you intercept the value

def filter(self, *args, **kwargs):
    if 'is_adult' in kwargs:
        value = kwargs.pop('is_adult')
        if value:
            kwargs['age__gte'] = 18
        else:
            kwargs['age__lt'] = 18
    return super().filter(*args, **kwargs)

And that's ignoring exclude and Q, and probably a lot of other cases.

Could we make that simpler first? 

On 16 Nov 2017 07:43, Shai Berger <s...@platonix.com> wrote:

On Thursday 16 November 2017 07:21:38 Josh Smeaton wrote:
>
> I don't agree with reimplementing lookups/transforms/funcs to produce the
> python version of a SQL concept. It's a leaky abstraction. Instead, I'd
> prefer the model author provides their python calculation:
>
>     is_adult = models.CalculatedField(Q(age__gte=18), lambda c: c.age >= 18)

(name shortened to fit in a 80-char line)

I disagree. The way I see it, these calculated fields should essentially
provide a declarative way to add an annotate() that's always going to be
there. There should be only one source of truth, and that's the database;
parallel implementations tend to disagree on fringe cases with disappointing
results (e.g. consider if age above is nullable -- the database then makes the
calculated field null, the python above makes it raise an exception). Or
consider calculated fields which are aggregates -- a Python version could very
easily become painfully inefficient.

>
> There may be destructuring/serialisation issues (migrations/pickle) using
> lambda, unless we can ignore these model fields during deserialisation.
>

That's another (though minor) argument against lambdas here.

No, the way I see it, the API should just use expressions. Of note, I think it
should also support the output_field keyword. At the hand-waving, brainstorming
level, I think we might, at some point, actually try to implement this by
creating objects in the database (views on Postgres, computed columns on
MySql, etc) -- so that the field is really available in all contexts.

My 2 cents,

Shai.


--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/fdf87ea3-aa91-452a-8336-d73dc92efe8d%40email.android.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to