Search code examples
djangodjango-rest-frameworkdjango-orm

Django annotate date with timedelta and increase


I am trying to query all the expired bookings and I don't have any fields like end_date, I have start_date and total itinerary__days.

This is my query:

import datetime
from django.db.models import Avg, Count, Min, Sum, FloatField, ExpressionWrapper, F, DateTimeField

trip = Booking.objects.annotate(
    end_date=ExpressionWrapper(
        F('start_date') + datetime.timedelta(days=F('itinerary__days')),
        output_field=DateTimeField()
    )
)

these are my models:

class Itinerary(models.Model):
    days = models.PositiveSmallIntegerField(_("Days"), null=True, blank=True)


class Booking(models.Model):
    itinerary = models.ForeignKey(
        Itinerary,
        on_delete=models.CASCADE
    )
    start_date = models.DateField(_("Start Date"), null=True, blank=True)

    def get_end_date(self):
        return self.start_date + datetime.timedelta(days=self.itinerary.days)

You may have noticed that I have a method to get end_date: get_end_date()

That is why I am trying to annotate to get the end date and query based on the end date to get expired booking.

in my query, you may notice this line: DateTime.timedelta(days=F('itineraray__days')) so you know timedelta days take argument type as an integer but passed this itinerary__days which caused the error.

Can anyone help me in this case?


Solution

  • In postgres you can try like this:

    qs = Booking.objects.annotate(
        end_date=ExpressionWrapper(
            F('start_date') + Cast(F("itinerary__days"), output_field=IntegerField()),
        output_field=DateField()
    ))