Skip to main content

A search (cmd+k) modal, for the Django admin UI, that searches your entire site.

Project description

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.7 - 3.12.
  • Django 3.2 - 5.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"""

Example

Add TextField results to search.

from django.contrib import admin
from django.db.models import Q, Field, TextField
from admin_site_search.views import AdminSiteSearchView


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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_admin_site_search-1.1.0.tar.gz (35.3 kB view details)

Uploaded Source

Built Distribution

django_admin_site_search-1.1.0-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

File details

Details for the file django_admin_site_search-1.1.0.tar.gz.

File metadata

File hashes

Hashes for django_admin_site_search-1.1.0.tar.gz
Algorithm Hash digest
SHA256 86bd0c2a132ae0db353c29eb3eebe9ca92e9208db09f43ee99b30aaba03a4cf4
MD5 a1f61c08b4e2203051c763b7512bf9e3
BLAKE2b-256 ee6c3c9a7e3c63e6dd5ed645ec499899c39d4914627f2e8638e295cbb89a0aa3

See more details on using hashes here.

File details

Details for the file django_admin_site_search-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_admin_site_search-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fee2318007f87ca2e996d10ead82aa11bdb1858caa7aa23758a164bcc2b0eab3
MD5 f473bfe5f8d3ffd5f99ba1219e7dee56
BLAKE2b-256 9df26ab1d366e52b250210056656022fb329c94fb1aa3457b80a1f32eb47d1f1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page