Home > Mobile >  django return multiple repetetive objects in query set filter template file
django return multiple repetetive objects in query set filter template file

Time:12-07

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 %}

CodePudding user response:

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.

  • Related