Skip to main content

django-admin-site-search

Test Lint PyPI Coverage Python Coverage Javascript Code style Pre-Commit PyPI version Downloads PyPI license

A global/site search modal for the Django admin.

Preview/demo GIF

Features

  • 🎩 Works out-of-the-box, with minimal config.
  • 🔎 Search performed on:
    • App labels.
    • Model labels and field attributes.
    • Model instances, with two options for a search method:
      1. model_char_fields (default): All CharField (and subclass) values, with __icontains.
      2. admin_search_fields: Invoke each ModelAdmin's get_search_results(...) method.
  • 🔒 Built-in auth: users can only search apps and models that they have permission to view.
  • ⚡ Results appear on-type, with throttling/debouncing to avoid excessive requests.
  • 🎹 Keyboard navigation (cmd+k, up/down, enter).
  • ✨ Responsive, and supports dark/light mode.
    • Django's built-in CSS vars are used to match your admin theme.

Requirements

  • Python 3.10 - 3.14.
  • Django 3.2 - 6.1.

Setup

1. Install

  1. Install with your package manager, e.g. pip install django-admin-site-search.
  2. Add admin_site_search to your INSTALLED_APPS setting.

2. Add View

  1. If you haven't already, override/extend the default AdminSite.
  2. Add the AdminSiteSearchView to your AdminSite:
from django.contrib import admin
from admin_site_search.views import AdminSiteSearchView

class MyAdminSite(AdminSiteSearchView, admin.AdminSite):
    ...

3. Add Templates

  1. If you haven't already, create admin/base_site.html in your templates/ directory.
    • Note: if your templates/ directory is inside of an app, then that app must appear in INSTALLED_APPS before your custom admin app.
  2. Include the admin_site_search templates:
{% extends "admin/base_site.html" %}

{% block extrahead %}
    {% include 'admin_site_search/head.html' %}
    {{ block.super }}
{% endblock %}

{% block footer %}
    {{ block.super }}
    {% include 'admin_site_search/modal.html' %}
{% endblock %}

{% block usertools %}
    {% include 'admin_site_search/button.html' %}
    {{ block.super }}
{% endblock %}

Notes

  • Along with styles, admin_site_search/head.html loads Alpine JS.
    • This is bundled into /static/, to avoid external dependencies.
  • The placement of modal.html and button.html are not strict, though the former would ideally be in a top-level position.
    • Django 4.x exposes {% block header %} - this is preferable to footer.

Customisation

Class attributes

class MyAdminSite(AdminSiteSearchView, admin.AdminSite):
    
    # Sets the last part of the search route (`<admin_path>/search/`).
    site_search_path: str = "search/"
    # Set the search method/behaviour.
    site_search_method: Literal["model_char_fields", "admin_search_fields"] = "model_char_fields" 

Methods

def match_app(
    self, request, query: str, name: str
) -> bool:
    """DEFAULT: case-insensitive match the app name"""

def match_model(
    self, request, query: str, name: str, object_name: str, fields: List[Field]
) -> bool:
    """DEFAULT: case-insensitive match the model and field attributes"""

def match_objects(
    self, request, query: str, model_class: Model, model_fields: List[Field]
) -> QuerySet:
    """DEFAULT: Returns the QuerySet after performing an OR filter across all Char fields in the model."""

def filter_field(
    self, request, query: str, field: Field
) -> Optional[Q]:
    """DEFAULT: Returns a Q 'icontains' filter for Char fields, otherwise None
    
    Note: this method is only invoked if model_char_fields is the site_search_method."""

def get_model_queryset(
    self, request, model_class: Model, model_admin: Optional[ModelAdmin]
) -> QuerySet:
    """DEFAULT: Returns the model class' .objects.all() queryset."""

def get_model_class(
    self, request, app_label: str, model_dict: dict
) -> Optional[Model]:
    """DEFAULT: Retrieve the model class from the dict created by admin.AdminSite"""

Examples

class CustomAdminSite(AdminSiteSearchView, admin.AdminSite):

    def get_model_class(self, *args, **kwargs) -> Optional[Model]:
        """Extends super() to skip the auth.User model"""
        model_class = super().get_model_class(*args, **kwargs)
        model_name = f"{model_class._meta.app_label}.{model_class._meta.object_name}"

        if model_name == "auth.User":
            return None

        return model_class

This can be adapted to skip multiple models, or applications.

class MyAdminSite(AdminSiteSearchView, admin.AdminSite):
    
    site_search_method: "model_char_fields"  
  
    def filter_field(self, request, query: str, field: Field) -> Optional[Q]:
        """Extends super() to add TextField support to site search"""
        if isinstance(field, TextField):
            return Q(**{f"{field.name}__icontains": query})
        return super().filter_field(query, field)

Note that this isn't done by default for performance reasons: __icontains on a large number of text entries is suboptimal.

Screenshots

Desktop, light theme, modal open

Mobile, light theme, modal closed Mobile, dark theme, modal open

Metadata

Release files for django-admin-site-search 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-admin-site-search 1.2.0
File Size Uploaded
django_admin_site_search-1.2.0.tar.gz 36.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-admin-site-search 1.2.0
File Interpreter ABI Platform
django_admin_site_search-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 73.3 kB

Release files / django_admin_site_search-1.2.0.tar.gz

Download URL django_admin_site_search-1.2.0.tar.gz
Size 36.2 kB
Tags Source
SHA-256 checksum
How to use checksums
357543a866edd787f3bed4c0ff2daff94ac40667998e02a019346ba3139af372
BLAKE2b-256 checksum
How to use checksums
87a3a1bdb9e2fe13c85b57358affaa231bd52703b2d34fe74a2a45d55a599963
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / django_admin_site_search-1.2.0-py3-none-any.whl

Download URL django_admin_site_search-1.2.0-py3-none-any.whl
Size 37.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
90449490c26cd56ed2c791807b1591512a9b2c21cc2d34a5fde28181f4ab8c4e
BLAKE2b-256 checksum
How to use checksums
0e1d9b3ac147d248474578fbdbd7754e0988667d28ca6b01c4966dd51c40bcdf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page