Reputation: 12084
I'm trying to implement search in django.
My view is as follows :
search_term = request.GET['search_term']
customers = Customer.objects.filter(
Q(chassis__icontains=search_term) | Q(registration__icontains=search_term) |
Q(email__icontains=search_term) | Q(firstname__icontains=search_term) |
Q(lastname__icontains=search_term))
calculations_data = []
if customers:
for customer in customers:
try:
calculation = Calculations.objects.get(customer=customer, user=request.user)
calculations_data.append({
'calculation': calculation,
'price': price_incl_vat(calculation.purchase_price),
'customer_fullname': '{} {} '.format(customer.firstname, customer.lastname),
'car_chassis': customer.chassis,
'car_registration': customer.registration,
})
except Calculations.DoesNotExist:
pass
context = {'search_term': search_term, 'total_result': len(calculations_data), 'calculation_data': calculations_data}
return render(request, 'master/search.html', context)
I have two models, calculations
and customer
. Inside calculation I have customer as ForeignKey, but it can be empty. Thus, every calculation doesn't need to have a customer.
In my example, if I have search term
the result is good, but If there is not search term, then I get only the calculations which have a customer.
But what I need is, if there is no search_term, I want to get all calculations.
Is there maybe a better way to write the query?
Thanks.
Upvotes: 1
Views: 111
Reputation: 4826
Since the results depend on availability of search_term
, why aren't you using if-else
on search_term
.
search_term = request.GET.get('search_term', None)
if search_term:
# when search term is not None
# get relevant calculations
else:
calculations = Calculations.objects.all()
# rest of code
You can further simplify your code when search_term
is not None
by putting the Q
objects directly in a Calculations.objects.filter()
itself (instead of getting relevant customers and then finding the relevant calculations). In Django, you can query on attributes of foreign key in Q
objects. You are first fetching Customers and then using those results to find Calculations. That will increase number of queries to database.
You can do something like following:
calculations = Calculations.objects.filter(
Q(customer__email__icontains=search_term) |
Q(customer__chassis_icontains=search_term)|
Q(....)).select_related('customer')
Related links:
1. Lookups that span relationships
2. select_related
Upvotes: 1
Reputation: 981
try this:
if customers:
try:
calculations = Calculations.objects.filter(user=request.user)
if customers:
calculations=calculations.filter(customer__in=customers)
for calculation in calculations:
calculations_data.append({
'calculation': calculation,
'price': price_incl_vat(calculation.purchase_price),
'customer_fullname': '{} {} '.format(customer.firstname, customer.lastname),
'car_chassis': customer.chassis,
'car_registration': customer.registration,
})
except Calculations.DoesNotExist:
pass
Upvotes: 0