Django return multiple repetetive objects in query set filter template file

I have implemented search bar functionality with autocomplete feature. All is good except the fact that in HTML serach results contain multiple the same object. For instance, when I put 2 in my searchbar I see 4 the same in my HTML file. What I want is to get unique objects.

enter image description here

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

{% extends 'base.html' %}
<title>{% block title %}search results{% endblock %}</title>
{% block search %}
{% include 'main/sidebar.html'%}
<link rel="stylesheet" type="text/css" href="/static/search.css">
    <div class="d-flex justify-content-end h-100 pb-4">
  <div>
    {% if user.is_authenticated %}
    <form action="{% url 'search_articles' %}" method="get" id="search">
      {% csrf_token %}
      <div class="searchbar " id="autocomplete">
        <input name="q" type="text" placeholder="Search articles" class="search_input">
        <a href="{% url 'search_articles' %}" class="search_icon"><i class="fas fa-search"></i></a>
        <ul class="autocomplete-result-list"></ul>
      </div>
    </form>
    {% endif %}</div>
    </div>
{% endblock search %}


{% block content %}
<div class="d-flex justify-content-start pb-4">Search results for my question: <div class="ml-1 fw-bold"> {{ query_name }} </div></div>
<div class="container-fluid pb-4">
<h4>Articles</h4>
<hr>
<div class="row row-flex row-cols-1 row-cols-md-3 g-4">
{% for article in search_articles %}
  <div class="col-lg-3 d-flex align-items-stretch">
    <a href="{{ article.get_absolute_url }}">
      <div class="card h-100 shadow text-left">
      <h5 class="card-header">{{article.title}}</h5>
        <img src="/static/preview_homepage3.png" class="card-img-top">
        <div class="card-body">
          <h5 class="card-title">{{ article.slug }}</h5>
          <p class="card-text">
            {% comment %} {% lorem 10 w %} {% endcomment %}
            {{article.body | safe | truncatechars:75}}
          </p>
    </a><br>
    {% include 'main/tag_cards.html' %}
  </div>
      <div class="card-footer">
        <small class="text-muted">{{ article.publish|date:"d F Y" }}</small>
      </div>
</div>
</div>
{% empty %}
<div class="container d-flex justify-content-center">No results</div>
{% endfor %}
</div>
</div>
<h4>Related questions</h4>
<hr>
<div class="container h-100 py-2 mb-4">
  {% for qa in qa_list %}
  <div class="card text-dark bg-light mb-3 text-left">
  <a href="{{ qa.get_absolute_url }}">
      <h5 class="card-header">Q: {{qa.title}}</h5>
      <div class="card-body">
          <div class="card-title text-justify">A: {{ qa.answer |safe | striptags }}</div>
          {% comment %} <p class="card-text"> {{ qa.author }}</p> {% endcomment %}
      </div>
      <div class="card-footer">
          <small class="text-muted">Published: {{qa.publish}}</small>
      </div>
      </a>
  </div>
  {% empty %}
  <p>No results</p>
  {% endfor %}

{% endblock %}

You can make use of Django's distinct() QuerySet method

.disctinct() Returns a new QuerySet that uses SELECT DISTINCT in its SQL query. This eliminates duplicate rows from the query results.

Change

article = Article.objects.filter(lookups)

to

article = Article.objects.filter(lookups).distinct()

Why does it happen?

In your case, this happens because you are using the Q object,

lookups = Q(title__icontains=query) | Q(tags__name__icontains=query)

suppose your search text is "test" and you have a row in the table with title="text" and tag_name="text", then the lookup will match both title and tag which leads to generating duplicate rows (since you are performing an OR operation in your lookkups) with the same result.

Back to Top