How to Implement Search with Dropdown Filter in Python Django

When I first started working with Django, implementing search functionality was always a core requirement for my projects. Over the years, combining a search box with a dropdown filter has not only improved user experience but also made data retrieval much more efficient. If you’re building a web app that requires users to filter results based on categories or types, this tutorial will guide you through creating a clean and functional search with a dropdown filter in Django.

In this article, I’ll walk you through the entire process with clear, concise code examples. We’ll build a simple project that allows users to search for US cities and filter them by state using a dropdown menu. This approach is practical and commonly needed in many real-world applications.

Set Up the Django Project

First, ensure you have Django installed. If not, install it via pip:

pip install django

Create a new Django project and app:

django-admin startproject citysearch
cd citysearch
python manage.py startapp locations

Add locations to your INSTALLED_APPS in settings.py:

INSTALLED_APPS = [
    #...
    'locations',
]

Read Payment Gateway Integration with Django

Create the Model

For this example, we’ll create a simple City model with two fields: name and state. The state field will be used in the dropdown filter.

# locations/models.py
from django.db import models

class City(models.Model):
    name = models.CharField(max_length=100)
    state = models.CharField(max_length=2)  # Use state abbreviation, e.g., CA, NY

    def __str__(self):
        return f"{self.name}, {self.state}"

Run migrations to create the database schema:

python manage.py makemigrations
python manage.py migrate

Add Sample Data

To test the search and filter, add some sample US cities and their states. You can do this via Django admin or directly in the Django shell:

python manage.py shell
from locations.models import City

City.objects.create(name='Los Angeles', state='CA')
City.objects.create(name='San Francisco', state='CA')
City.objects.create(name='New York', state='NY')
City.objects.create(name='Buffalo', state='NY')
City.objects.create(name='Chicago', state='IL')
City.objects.create(name='Houston', state='TX')
City.objects.create(name='Dallas', state='TX')
exit()

Check out How to Add Items to Cart in Django in Python?

Create the Search and Filter Form

We’ll create a simple form with a text input for the city name and a dropdown for the state filter.

# locations/forms.py
from django import forms

STATE_CHOICES = [
    ('', 'All States'),
    ('CA', 'California'),
    ('NY', 'New York'),
    ('IL', 'Illinois'),
    ('TX', 'Texas'),
]

class CitySearchForm(forms.Form):
    query = forms.CharField(required=False, label='Search City')
    state = forms.ChoiceField(choices=STATE_CHOICES, required=False, label='Filter by State')

Write the View

The view will handle the form data, filter the queryset accordingly, and render the results.

# locations/views.py
from django.shortcuts import render
from .models import City
from .forms import CitySearchForm

def city_search(request):
    form = CitySearchForm(request.GET or None)
    cities = City.objects.all()

    if form.is_valid():
        query = form.cleaned_data.get('query')
        state = form.cleaned_data.get('state')

        if query:
            cities = cities.filter(name__icontains=query)
        if state:
            cities = cities.filter(state=state)

    context = {
        'form': form,
        'cities': cities,
    }
    return render(request, 'locations/city_search.html', context)

Read Check if Python Dictionary is Empty

Create the Template

Now, create the template to display the form and results.

<!-- locations/templates/locations/city_search.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>City Search with Dropdown Filter</title>
</head>
<body>
    <h1>Search US Cities</h1>
    <form method="get">
        {{ form.query.label_tag }} {{ form.query }}
        {{ form.state.label_tag }} {{ form.state }}
        <button type="submit">Search</button>
    </form>

    <h2>Results</h2>
    <ul>
        {% for city in cities %}
            <li>{{ city.name }}, {{ city.state }}</li>
        {% empty %}
            <li>No cities found.</li>
        {% endfor %}
    </ul>
</body>
</html>

Configure URLs

Add the URL pattern to route requests to the view.

# citysearch/urls.py
from django.contrib import admin
from django.urls import path
from locations.views import city_search

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', city_search, name='city_search'),
]

Check out Python Filter Not in Django

Test the Application

Run the Django development server:

python manage.py runserver

Open your browser and navigate to http://127.0.0.1:8000/. You should see a search box and a dropdown filter for states.

You can refer to the screenshot below to see the output.

search form Django

Try searching for cities like “San” and filtering by “California.” The results will update accordingly.

Read Union Operation on Django Models

Alternative Method: Use Django Filter Library

For more advanced filtering, I recommend using the django-filter library, which simplifies filtering logic and integrates well with Django generic views.

Install it:

pip install django-filter

Create a filter class:

# locations/filters.py
import django_filters
from .models import City

class CityFilter(django_filters.FilterSet):
    name = django_filters.CharFilter(lookup_expr='icontains')
    state = django_filters.ChoiceFilter(choices=[
        ('CA', 'California'),
        ('NY', 'New York'),
        ('IL', 'Illinois'),
        ('TX', 'Texas'),
    ])

    class Meta:
        model = City
        fields = ['name', 'state']

Update the view:

# locations/views.py
from django.shortcuts import render
from .models import City
from .filters import CityFilter

def city_search(request):
    city_filter = CityFilter(request.GET, queryset=City.objects.all())
    return render(request, 'locations/city_search.html', {'filter': city_filter})

Update the template:

<form method="get">
    {{ filter.form.as_p }}
    <button type="submit">Search</button>
</form>

<ul>
    {% for city in filter.qs %}
        <li>{{ city.name }}, {{ city.state }}</li>
    {% empty %}
        <li>No cities found.</li>
    {% endfor %}
</ul>

You can refer to the screenshot below to see the output.

django search field

This method reduces boilerplate code and is especially useful for larger projects.

Implementing search with dropdown filters in Django is easy once you understand how to combine form inputs with queryset filtering. Whether you choose the manual form method or the django-filter library, both approaches provide clean, maintainable code that enhances your users’ ability to find exactly what they need.

I hope this tutorial helps you build better search experiences in your Django projects. If you have any questions or want me to cover related topics, feel free to reach out!

You can explore more Django tutorials and advanced techniques at PythonGuides.com to keep improving your skills and build efficient, scalable web applications.

You may also read other Django-related articles.

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.