user9252255
user9252255

Reputation:

Django: Making queries the efficient way

Would you consider this the right/efficient way to make queries?

discount_code_get = request.GET.get('discount')
    discount_code = Discount.objects.filter(code=discount_code_get)
    discount_code_exists = discount_code.exists()
    if discount_code_exists:
        print(discount_code.first().value)

Upvotes: 1

Views: 54

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476503

You here perform two queries: an EXISTS and a fetch. You can merge it into one:

discount_code_get = request.GET.get('discount')
discount_code= Discount.objects.filter(code=discount_code_get).first()
if discount_code is not None:
    return discount_code.value

This works since .first() returns None if it can not find such database row.

Or even more efficient (given value is non-NULLable):

# In case value is non-NULLable

discount_code_get = request.GET.get('discount')
discount_value = Discount.objects.values_list(
    'value', flat=True
).filter(code=discount_code_get).first()
if discount_value is not None:
    return discount_value

In case the code is a unique field, it is more idiomatic to use a try-except here:

# in case code is unique

discount_code_get = request.GET.get('discount')
try:
    discount_value = Discount.objects.values_list(
        'value', flat=True
    ).get(code=discount_code_get)
except Discount.DoesNotExist:
    pass
else:
    print(discount_value)

Using .values_list(..) will reduce the number of columns that are fetched (and deserialized). Although that is typically not a huge boost, it can be significant if the number of columns is large, or the data stored in it is large, since then we save on deserializing attributes, that are never used later in the process.

Upvotes: 1

neverwalkaloner
neverwalkaloner

Reputation: 47354

From the docs:

Additionally, if a some_queryset has not yet been evaluated, but you know that it will be at some point, then using some_queryset.exists() will do more overall work

You can simple use first() to get required object. Since first returns None if object does not exist you can do something like this:

discount_code = Discount.objects.filter(code=discount_code_get).first()
if discount_code:
    print(discount_code)

Upvotes: 2

Related Questions