darkhorse
darkhorse

Reputation: 8722

Combining and slicing 2 querysets before hitting the database in Django

I am trying to get a queryset from mergeing two querysets. The conditions are as follows:

Lets say I have a model called MyModel, with a field called value which stores integers, however, the value can be null.

I know querysets in Django are lazy, but Im not sure if the conditions are being met in the following line of code.

qs = MyModel.objects.exclude(value__isnull=True).filter(value__gte=250).order_by('-value') | MyModel.objects.exclude(value__isnull=False)
objects = qs[:20]

Basically, I am filtering out first where the value is not null, ordering them according to value, and then at the end, I am adding the ones excluded. Is this meeting my conditions? That is, is the database being hit once? Moreover, is there a better way to do this without the | operator?

Note: I know this can be done without merging querysets, but for the sake of this question, lets assume that having 2 querysets like this is absolutely necessary.

Edit: Added third condition, which I thought was implied. My bad.

Upvotes: 0

Views: 301

Answers (1)

Kamil Niski
Kamil Niski

Reputation: 4765

Yes it works as you say. This is undocumented implementation of union of querysets. It will hit the database only once.

You can verify that it is coerced into one query with by print(qs.query)

Also i recommend checking FAQ: How can I see the raw SQL queries Django is running?

from django.db import connection
connection.queries

It will allow you to inspect queries that hit database

Upvotes: 1

Related Questions