Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter in range of two date fields

I have something like this:

 class Model(models.Model):
      start = models.DateTimeField()
      end = models.DateTimeField()

and I want to get all models that follow the following constraints:

given two query parameters qstart, qend

  • model.end > qstart
  • model.start < q.end

which would give all Model objects that lie between in the range of the two dates. I saw you can do

 Model.objects.filter(date__range=[qstart, qend])

however, that operates on a single field, where as I need to operate on 2 separate fields.

like image 741
user3408657 Avatar asked Jan 28 '18 00:01

user3408657


People also ask

How do you filter a date range?

On the View tab, click the Filter down arrow and choose Date Range on the dropdown list. The Date Range dialog box appears. In the show tasks that start or finish after box, fill in the start of the date range and click OK. In the and before box, fill in the end of the date range and click OK.


1 Answers

Adapted from Django docs

filter()

filter(**kwargs)

Returns a new QuerySet containing objects that match the given lookup parameters. Multiple parameters are joined via AND in the underlying SQL statement.

In your case:

Model.objects.filter(start__lte=qend, end__gte=qstart)

Chaining filters

The result of refining a QuerySet is itself a QuerySet, so it’s possible to chain refinements together. In your case, for example:

Model.objects.filter(
     end__gte=qstart
).filter(
     start__lte=qend
)

This takes the initial QuerySet of all entries in the database, adds a filter, then another filter. The final result is a QuerySet containing all entries with end > qstart and start < qend.

Q objects

If you need to execute more complex queries (for example, queries with OR statements), you can use Q objects.

Q() objects make it possible to define and reuse conditions. Q objects can be combined using the & and | operators. When an operator is used on two Q objects, it yields a new Q object.

In your case:

from django.db.models import Q

Model.objects.get(
    Q(end__gte=qstart) & Q(start__lte=qend)
)
like image 145
Kevin L. Avatar answered Sep 21 '22 13:09

Kevin L.