'How to display a list of search results in Django 4

I'm writing a Django app to manage sales leads. From the template that lists a page of leads, I want to give the user the ability to search all leads using first name and last name as the search criteria. When I type in a last name and press enter, the page flickers but remains on the same page rather than the template I created to list the search results.

My views, urls, and templates are below. What have I missed?

views.py

class LeadsListView(ListView):
    model = Lead
    template_name = 'leads/list.html'
    context_object_name = 'leads_list'
    paginate_by = 10

    def get_queryset(self):
        return Lead.objects.order_by('id')

class LeadsSearchResultsView(ListView):
    model = Lead
    context_object_name = 'search_results'
    template_name = 'leads/search_results.html'
    paginate_by = 10

    def get_queryset(self):
        query = self.request.GET.get('q')

        return Lead.objects.filter(
            Q(last__icontains=query) | Q(first__icontains=query)
        )

urls.py

from django.urls import path
from .views import LeadsListView, LeadsDetailView, LeadsCreateView
from .views import LeadsSearchResultsView

app_name = 'lead'

urlpatterns = [
    path('', LeadsListView.as_view(), name='list'),
    path('<int:pk>/', LeadsDetailView.as_view(), name='detail'),
    path('', LeadsCreateView.as_view(), name='create'),
    path('', LeadsSearchResultsView.as_view(), name='search_results'),
]

The template that (successfully!) lists the leads, list.html:

{% extends 'base.html' %}

{% block content %}
<nav aria-label="Page navigation example">
    <ul class="pagination">
        {% if page_obj.has_previous %}
        <li class="page-item">
            <a class="page-link" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
                <span class="sr-only">Previous</span>
            </a>
        </li>
        {% endif %}
        {% if page_obj.has_next %}
        <li class="page-item">
            <a class="page-link" href="?page={{ page_obj.next_page_number }}" aria-label="Next">
                <span aria-hidden="true">&raquo;</span>
                <span class="sr-only">Next</span>
            </a>
        </li>
        {% endif %}
        <form action="{% url 'lead:search_results' %}" method="get">
            <input type="search" name="q" value="{{ request.GET.q }}" placeholder="Search by last name"
                class="form-control">
        </form>
    </ul>
</nav>

<table class="table table-hover table-bordered">
    <thead>
        <tr>
            <th scope="col">Lead No.</th>
            <th scope="col">First</th>
            <th scope="col">Last</th>
            <th scope="col">Phone</th>
            <th scope="col">Email</th>
            <th scope="col">Zip Code</th>
        </tr>
    </thead>
    <tbody>
        {% for lead in page_obj %}
        <tr>
            <td><a href="{% url 'lead:detail' lead.pk %}">{{ lead.pk }}</a></td>
            <td>{{ lead.first }}</td>
            <td>{{ lead.last }}</td>
            <td>{{ lead.mobile }}</td>
            <td>{{ lead.email }}</td>
            <td>{{ lead.zipcode }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endblock content %}

And finally, the template that should list the results of the search, but doesn't, search_results.html:

{% extends 'base.html' %}

{% block content %}
<nav aria-label="Page navigation example">
    <ul class="pagination">
        {% if page_obj.has_previous %}
        <li class="page-item">
            <a class="page-link" href="?page={{ page_obj.previous_page_number }}" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
                <span class="sr-only">Previous</span>
            </a>
        </li>
        {% endif %}
        {% if page_obj.has_next %}
        <li class="page-item">
            <a class="page-link" href="?page={{ page_obj.next_page_number }}" aria-label="Next">
                <span aria-hidden="true">&raquo;</span>
                <span class="sr-only">Next</span>
            </a>
        </li>
        {% endif %}
        <form action="{% url 'lead:search_results' %}" method="get">
            <input type="search" name="q" value="{{ request.GET.q }}" placeholder="Search by last name"
                class="form-control">
        </form>
    </ul>
</nav>

<table class="table table-hover table-bordered">
    <thead>
        <tr>
            <th scope="col">Lead No.</th>
            <th scope="col">First</th>
            <th scope="col">Last</th>
            <th scope="col">Phone</th>
            <th scope="col">Email</th>
            <th scope="col">Zip Code</th>
        </tr>
    </thead>
    <tbody>
        {% for lead in page_obj %}
        <tr>
            <td><a href="{% url 'lead:detail' lead.pk %}">{{ lead.pk }}</a></td>
            <td>{{ lead.first }}</td>
            <td>{{ lead.last }}</td>
            <td>{{ lead.mobile }}</td>
            <td>{{ lead.email }}</td>
            <td>{{ lead.zipcode }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endblock content %}


Solution 1:[1]

Below is your url.py file

urlpatterns = [
    path('', LeadsListView.as_view(), name='list'),
    path('<int:pk>/', LeadsDetailView.as_view(), name='detail'),
    path('', LeadsCreateView.as_view(), name='create'),
    path('', LeadsSearchResultsView.as_view(), name='search_results'),
]

Here, you are calling 3 different views class with the same url '' which is wrong.

You can correct the same and proceed further.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Subhash Tulsyan