Как осуществлять поиск и фильтрацию по нескольким связанным моделям?
Я создаю систему поиска и фильтрации, в которой пользователь может вводить и искать соответствующие курсы и учебные заведения. Вот структура моей модели:
Структура модели:
Institutions:
- Name
- Id
- email
- address
...... etc.
Courses:
- owner = models.ForeignKey(Institution, on_delete=models.CASCADE)
- name
- ref
- license
- overview
..... etc
Теперь, используя все вышесказанное, я создал строку поиска, в которой пользователю нужно что-то ввести, а затем нажать кнопку "поиск" или клавишу "Enter". Это покажет результаты поиска. Мой код поиска:
query = request.GET.get('q')
courses = Course.objects.filter(name__icontains=query)
institution= Institution.objects.filter(name__icontains=query)
queryset_chain = chain(courses,institution)
Проблема заключается в том, что я хочу отобразить результат следующим образом.
сценарий 1:
Допустим, что курс и институт имеют одинаковые названия, например, "tech".
Когда пользователь ищет "tech", мне нужно показать результат следующим образом:
Название учреждения
- Название курса
сценарий 2:
Допустим, что курс имеет название "техник", но не институт имеет такое название.
Когда пользователь ищет "tech", мне нужно показать результат следующим образом: В этом случае мне нужно показать название курса, а также соответствующее учебное заведение название:
Название учреждения
- Название курса
сценарий 3:
где институт имеет название "техник". Но нет курса название.
Название учреждения
- любое произвольное имя курса
Как работать с таким видом объединенного поиска и фильтра?
Поскольку я не могу воспроизвести ваше приложение, я могу только дать вам представление о том, как решить эту проблему. Модель Course является дочерней по отношению к модели Institution, вы можете применить prefetch_related() или select_related() для предотвращения N+1 запросов. Эти коды обобщают все три сценария, используя объект Q() из Django, поскольку вы можете использовать выражение OR -> | на нем.
from django.db.models import Q
query = request.GET.get('q')
courses = Course.objects.prefetch_related('institution') \
.filter(Q(institution_set__name__icontains=query) |
Q(course_set__name__icontains=query))
Вам также не нужно использовать chain, попробуйте regroup. Я не уверен, какого результата вы ожидаете от третьего сценария, но, возможно, добавление условия пойдет на пользу.