1

This can be a duplicated of this question but I didn't understand if it is possible or not.

I have two models that are unrelated (or have a nested nested relation)

class Cycle(models.Model):

    start_date = models.DateField()
    end_date = models.DateField()

class Event(models.Model)
    created_at = models.DateField()

What I want is filter the current Cycle and to annotate the number of Events that were created between the Cycle's start_date and end_date, all in one query.

What I have so far:

now = timezone.now()

number_events = Event.objects\
            .filter(created_at__gte=OuterRef('start_date'), created_at__lte=OuterRef('end_date'))

cycle = Cycle.objects \
            .filter(start_date__lte=now, end_date__gte=now) \
            .annotate(number_events=Count(number_events)) \
            .first()

This creates an invalid syntax, saying subquery must return only one column

If I add values("id") in the number_events query, it raises more than one row returned by a subquery used as an expression

If I add values("id")[:1] it works, but only counts one Event

And if I try to do the query in SQL I can retrieve data

SELECT *,
       (select COUNT(*) AS "number_events"
        FROM "events_event" U0
        WHERE (U0."created_at" >= "cycles_cycle"."start_date" AND
               U0."created_at" <= "cycles_cycle"."valid_until"))
FROM "cycles_cycle"
WHERE ("cycles_cycle"."start_date" <= '2022-06-01' AND
       "cycles_cycle"."end_date" >= '2022-06-01')
GROUP BY "cycles_cycle"."id"
limit 1;

Is there a way to create this query in django, or is it impossible while being unrelated models?

Enorio
  • 65
  • 8

0 Answers0