Goro
Goro

Reputation: 10249

Combining queries in django

In my application I do the following lookup:

my_datapoint = Datapoint.objects.filter(timestamp_lte = desired_time).reverse()[0]

I have to do this several times, for records that are not adjacent in time.

Is there a way to make this more efficient than having several separate QuerySets? Can I combine them?

Upvotes: 0

Views: 2529

Answers (2)

jdi
jdi

Reputation: 92637

This has been asked a ton of times on here. You can use chain

from itertools import chain

combined = chain(qs1, qs2, ...)
for item in combined:
    # foo

One alternative to completely separate queryset objects, is to see if you can do it with "OR" queries using the Q objects:
https://docs.djangoproject.com/en/1.4/topics/db/queries/#complex-lookups-with-q-objects

Example from the docs

Poll.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)

This example says "objects that have a question starting with 'Who', AND, objects with either this pub date OR that pub date"

Upvotes: 4

xbtsw
xbtsw

Reputation: 734

By "more efficient", I assume you mean you want to avoid hit database multiple times. In that case, you should query once, and then loop through it yourself, also use QuerySet to sort is better than reverse()

my_datapoint = Datapoint.objects.filter(timestamp_lte = max_desired_time).order_by('-timestamp')
def getLatest(desired_time):
    for item in my_datapoint:
        if item.timestamp <= desired_time:
            return item

If you just want simpler syntax, use chain as jdi suggested.

Upvotes: 1

Related Questions