Reputation: 2189
Considering a very simple model as such:
class Thing(models.Model):
attribute = models.IntegerField(choices=[1,2,3])
I would like all Things, except those with attribute=2.
But I do want these with attribute=2 if there is no Things with attribute other than 2 in the result set.
How can I get this result with a single query?
[Edit]
Actually I only need the first Thing that has an attribute different than 2, or the first thing with an attribute of 2 if this is the only kind of Thing available.
I have been able to achieve that with a function as
def get_thing():
things_per_attribute = [
Thing.objects.filter(attribute=value)
for value in [1, 3, 2]
]
for thing in things_per_attribute:
if thing.count() > 0:
return thing[0]
return None
I am still interested to see if anyone can propose a 1-query-solution.
Upvotes: 1
Views: 284
Reputation: 2398
One query:
from django.db.models import BooleanField, Case, When
Thing.objects.annotate(
attribute_is_two=Case(
When(attribute=2, then=True),
default=False,
output_field=BooleanField()
),
).order_by('-attribute_is_two').first()
Two queries:
def get_thing():
thing = Things.objects.exclude(attribute=2).first()
if thing:
return thing
return Thing.objects.first()
Upvotes: 1