Reputation: 61
I am creating an search and filter system in which user can type and search related courses and institutions. This is my model structure:
Model Structure:
Institutions:
- Name
- Id
- email
- address
...... etc.
Courses:
- owner = models.ForeignKey(Institution, on_delete=models.CASCADE)
- name
- ref
- license
- overview
..... etc
Now by using the above, i have created a search bar in which user needs to type something and then press "search" button or else press "Enter" key. This will show search results. My search code:
query = request.GET.get('q')
courses = Course.objects.filter(name__icontains=query)
institution= Institution.objects.filter(name__icontains=query)
queryset_chain = chain(courses,institution)
So the problem here is that, I want to display the result as follows.
scenario 1:
Lets say that course and Institution has same name like "tech".
When user search for "tech", I need to show result as follows:
Institution Name
scenario 2:
Lets say that course has name as "tech" but not Institution has that name.
When user search for "tech", I need to show result as follows: In this case, I need to show the Course name and also correspondant Institution name:
Institution Name
scenario 3:
where Institution has "tech" as name. But no course name.
Institution Name
How to handle this kind of clubbed search and filter ?
Upvotes: 2
Views: 77
Reputation: 442
Since I cannot replicate your app, I can only give you an idea of how to solve this. Course
model is the child of the Institution
model, you can apply prefetch_related()
or select_related()
to prevent N+1 queries. These codes sum up all three scenarios using the Q()
object from Django since you can use the OR -> |
expression on it.
from django.db.models import Q
query = request.GET.get('q')
courses = Course.objects.select_related('institution') \
.filter(Q(institution_set__name__icontains=query) |
Q(course_set__name__icontains=query))
You also don't need to use chain
, try regroup. I'm not sure what result you expect for the third scenario, but maybe adding the condition will do good.
Upvotes: 1