Reputation: 189
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
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.
Upvotes: 6
Views: 12539
Reputation: 204
import datetime
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))
Reference: https://docs.djangoproject.com/en/3.0/ref/models/querysets/#range
Upvotes: 1
Reputation: 1471
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)
)
Upvotes: 13
Reputation: 1215
Use simply:
Model.objects.filter(end__gte=qstart).filter(start__lte=qend).all()
Upvotes: 1
Reputation: 1579
Just add additional condition:
Model.objects.filter(start__lte=qend, end__gte=qstart)
Where qend
, qstart
must be datetime.date
objects
Upvotes: 3