6

Is there a way to make this query work with Django?

stage = Task.objects.filter(id = input_stage.id)\
            .update(start_date = max(data.get('start_date'), F('start_date')),
                    finish_date = max(data.get('finish_date'), F('finish_date')))

Now I get an error:

TypeError: '>' not supported between instances of 'F' and 'datetime.date'

1 Answer 1

10

The max between two fields in a database is in Django the Greatest [Django-doc], so the query should read something like:

from django.db.models import F, Value
from django.db.models.functions import Greatest

Task.objects.filter(
    id=input_stage.id
).update(
    start_date=Greatest(Value(data.get('start_date')), F('start_date')),
    finish_date=Greatest(Value(data.get('finish_date')), F('finish_date'))
)

You also might want to convert the data.get('start_date'), etc. to date objects.

Mind that a .update(…) [django-doc] does not return a QuerySet, but:

(...) and returns the number of rows matched (which may not be equal to the number of rows updated if some rows already have the new value).

Sign up to request clarification or add additional context in comments.

4 Comments

Nice! Thank you!
I see you have updated your answer. Is there any difference to use Value or not using it?
@Chiefir: well "The Zen of Python" says "explicit over implicit", I think it is more safe to wrap it in a Value given the fields contain a value, and not a field name, since some of these database functions tend to pick the fieldname. So I think Value(..) is at least safer (although at the moment I can not test it). If you however data.get('start_date') contains the field name, then it should be an F(..).
Ok, thank you. P.S. data is just a dict with date.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.