Django возвращает несколько повторяющихся объектов в файле шаблона фильтра набора запросов
Я реализовал функциональность строки поиска с функцией автозаполнения. Все хорошо, за исключением того, что в результатах поиска HTML содержится несколько одинаковых объектов. Например, когда я помещаю 2
в строку поиска, я вижу 4 одинаковых объекта в моем HTML файле. Я хочу получить уникальные объекты.
views.py
@login_required
def search_address_qa(request):
query = request.GET.get('title')
payload = []
if query:
lookups = Q(title__icontains=query)
address_objects = Article.objects.filter(lookups)
address_objects_qa = QA.objects.filter(lookups)
for address_object in address_objects or address_objects_qa:
payload.append(address_object.title)
return JsonResponse({'status':200, 'data': payload})
@login_required
def search_articles(request):
query = request.GET.get('q')
article = Article.objects.filter(title__icontains=query)
qa_list = QA.objects.filter(title__icontains=query)
if query is not None:
lookups = Q(title__icontains=query) | Q(tags__name__icontains=query)
article = Article.objects.filter(lookups)
qa_list = QA.objects.filter(lookups)
context = {
'search_articles': article,
'query_name': query,
'qa_list': qa_list
}
return render(request, 'search/search_articles.html', context)
search_view.html
Вы можете использовать метод Django distinct() QuerySet
.disctinct() Возвращает новый QuerySet, который использует SELECT DISTINCT в своем SQL-запросе. Это исключает дубликаты строк из результатов запроса.
Change
article = Article.objects.filter(lookups)
to
article = Article.objects.filter(lookups).distinct()
Почему это происходит?
В вашем случае это происходит потому, что вы используете объект Q,
lookups = Q(title__icontains=query) | Q(tags__name__icontains=query)
Предположим, что ваш текст поиска "test" и у вас есть строки в таблице с title="text" и tag_name="text", тогда поиск будет соответствовать и заголовку, и тегу, что приведет к генерации дублирующих строк (поскольку вы выполняете операцию OR в поиске) с одинаковым результатом.