Skip to main content

Execute Django ORM queries directly from the admin interface

Project description

Django Admin Query Executor

A powerful Django admin extension that allows you to execute Django ORM queries directly from the admin interface. It supports complex queries including Q() objects, annotations, aggregations, and all standard Django ORM methods.

Django Admin Query Executor Python Support License

Features

  • Direct Query Execution: Execute Django ORM queries directly from the admin changelist view
  • Seamless Integration: Query results replace the standard admin list view
  • Full Django ORM Support: Use Q(), F(), Count(), Sum(), Avg(), and other Django model functions
  • Custom Imports: Add your own modules, functions, and classes to the query execution environment
  • Query History: Automatically saves your recent queries for quick re-execution
  • Favorite Queries: Save frequently used queries with custom names
  • Collapsible Interface: Clean, collapsible UI that doesn't clutter your admin
  • Comprehensive Dark Mode Support:
    • Automatically adapts to system preferences
    • Compatible with Django admin's built-in dark mode
    • Works with popular admin themes (Grappelli, Jazzmin, etc.)
    • Smooth transitions between light and dark themes
    • Accessible color contrasts in both modes
  • Security: Queries execute in a restricted environment with whitelisted functions
  • Smart Result Detection: Automatically handles both queryset and scalar results

Installation

pip install django-admin-query-executor

Quick Start

  1. Add django_admin_query_executor to your INSTALLED_APPS:
INSTALLED_APPS = [
    ...
    'django_admin_query_executor',
    ...
]
  1. Add the QueryExecutorMixin to your ModelAdmin classes:
from django.contrib import admin
from django_admin_query_executor import QueryExecutorMixin
from .models import MyModel

@admin.register(MyModel)
class MyModelAdmin(QueryExecutorMixin, admin.ModelAdmin):
    list_display = ['id', 'name', 'created_at']

    # Optional: Define custom example queries for this model
    query_examples = [
        ("Active items", "MyModel.objects.filter(is_active=True)"),
        ("Recent items", "MyModel.objects.filter(created_at__gte=timezone.now() - timedelta(days=7))"),
        ("Count by status", "MyModel.objects.values('status').annotate(count=Count('id'))"),
    ]

Usage

  1. Navigate to any model's admin changelist that uses QueryExecutorMixin
  2. Click "Execute Django Query" to expand the query interface
  3. Enter your Django ORM query (e.g., MyModel.objects.filter(status='active'))
  4. Click "Execute Query"
  5. The admin list updates to show your query results

Query Examples

# Filter queries
Book.objects.filter(author__name__icontains='Smith')
Book.objects.filter(Q(title__icontains='Django') | Q(title__icontains='Python'))

# Annotations and aggregations
Book.objects.annotate(review_count=Count('reviews')).filter(review_count__gt=10)
Book.objects.aggregate(avg_price=Avg('price'), total_books=Count('id'))

# Complex queries with joins
Author.objects.filter(books__published_date__year=2023).distinct()
Book.objects.select_related('author', 'publisher').filter(price__lt=50)

# Counting and existence checks
Book.objects.filter(category='Fiction').count()
Book.objects.filter(reviews__rating__gte=4).exists()

# Using custom imports (see Custom Imports section)
Book.objects.filter(title__in=json.loads('[\"Book1\", \"Book2\"]'))
Book.objects.filter(created_date__gte=datetime.now() - timedelta(days=30))

Configuration

Custom Imports

You can add custom modules, functions, and classes to the query execution environment in two ways:

Method 1: Django Settings (Global)

Add a QUERY_EXECUTOR_CUSTOM_IMPORTS setting to your Django settings file:

# settings.py
QUERY_EXECUTOR_CUSTOM_IMPORTS = {
    # Import entire modules
    'json': 'json',
    'datetime': 'datetime',
    'timedelta': 'datetime.timedelta',
    'timezone': 'django.utils.timezone',

    # Import specific functions/classes from modules
    'settings': ('django.conf', 'settings'),
    'Decimal': ('decimal', 'Decimal'),

    # Import your custom models and functions
    'Listing': 'numi.models.Listing',
    'Coin': 'numi.models.Coin',
    'custom_function': 'myapp.utils.custom_function',
}

Method 2: ModelAdmin Class Attribute (Per-Admin)

Override the custom_imports attribute in your ModelAdmin:

@admin.register(PossibleMatch)
class PossibleMatchAdmin(QueryExecutorMixin, admin.ModelAdmin):
    # Custom imports specific to this admin
    custom_imports = {
        'json': 'json',
        'settings': ('django.conf', 'settings'),
        'Listing': 'numi.models.Listing',
        'Coin': 'numi.models.Coin',
        'timedelta': ('datetime', 'timedelta'),
        'now': ('django.utils.timezone', 'now'),
    }

    query_examples = [
        ("High confidence matches", "PossibleMatch.objects.filter(textual_score__gt=0.8, image_score__gt=0.8)"),
        ("Recent matches", "PossibleMatch.objects.filter(textual_match_date__gte=now() - timedelta(days=7))"),
        ("Using settings", "PossibleMatch.objects.filter(textual_score__gte=settings.TEXTUAL_SCORE_CUTOFF)"),
        ("With JSON data", "PossibleMatch.objects.filter(id__in=json.loads('[1, 2, 3]'))"),
    ]

Import Format Examples

custom_imports = {
    # Simple module imports
    'json': 'json',                    # import json
    'os': 'os',                        # import os

    # Import specific items from modules
    'settings': ('django.conf', 'settings'),              # from django.conf import settings
    'timezone': ('django.utils', 'timezone'),             # from django.utils import timezone
    'timedelta': ('datetime', 'timedelta'),               # from datetime import timedelta
    'Decimal': ('decimal', 'Decimal'),                    # from decimal import Decimal

    # Import your custom models
    'User': ('django.contrib.auth.models', 'User'),      # from django.contrib.auth.models import User
    'MyModel': ('myapp.models', 'MyModel'),               # from myapp.models import MyModel

    # Import custom functions/utilities
    'my_function': ('myapp.utils', 'my_function'),        # from myapp.utils import my_function
    'calculate_score': ('myapp.scoring', 'calculate_score'),
}

Custom Change List Templates

The mixin automatically overrides the ModelAdmin's change_list_template if the default template is in use. If your ModelAdmin uses a custom template, the template will need to extend admin/query_executor_change_list.html:

{% extends "admin/query_executor_change_list.html" %}

Custom Example Queries

Define model-specific example queries by adding a query_examples attribute to your ModelAdmin:

class BookAdmin(QueryExecutorMixin, admin.ModelAdmin):
    query_examples = [
        ("Bestsellers", "Book.objects.filter(is_bestseller=True)"),
        ("By price range", "Book.objects.filter(price__gte=20, price__lte=50)"),
        ("Review stats", "Book.objects.annotate(avg_rating=Avg('reviews__rating')).filter(avg_rating__gte=4.0)"),
        ("Using custom imports", "Book.objects.filter(created_date__gte=now() - timedelta(days=30))"),
    ]

Customizing Query History

Control the number of queries saved in history:

class BookAdmin(QueryExecutorMixin, admin.ModelAdmin):
    query_history_limit = 10  # Default is 5

Supported Django ORM Features

Query Methods

  • filter(), exclude(), get()
  • order_by(), reverse(), distinct()
  • values(), values_list()
  • select_related(), prefetch_related()
  • annotate(), aggregate()
  • first(), last(), exists(), count()

Query Expressions

  • Q() for complex queries
  • F() for field references
  • Count(), Sum(), Avg(), Max(), Min()
  • Case(), When() for conditional expressions
  • Exists(), OuterRef(), Subquery()

Database Functions

  • String functions: Lower(), Upper(), Length(), Concat()
  • Date functions: TruncDate(), Extract(), Now()
  • Type casting: Cast(), Coalesce()

Dark Mode Support

The package includes comprehensive dark mode support that:

  • Auto-detects your system's color scheme preference
  • Integrates seamlessly with Django admin's native dark mode
  • Supports popular admin themes including:
    • Django's built-in dark mode
    • Grappelli dark theme
    • Django Jazzmin dark mode
    • Django Admin Interface dark themes
  • Provides smooth transitions when switching between themes
  • Ensures accessibility with proper color contrasts
  • Includes custom CSS variables for easy customization

Customizing Dark Mode Colors

You can override the default colors by adding CSS variables to your admin CSS:

.query-executor-container {
    --qe-bg-primary: #1a1a1a;
    --qe-text-primary: #ffffff;
    --qe-button-primary-bg: #007bff;
    /* See query_executor_dark_mode.css for all available variables */
}

Security

The query executor runs in a restricted environment with:

  • Whitelisted functions and classes only
  • No access to private attributes or methods
  • No direct database access beyond Django ORM
  • No file system or network access
  • Custom imports are loaded with error handling
  • Failed imports are logged but don't break functionality

Requirements

  • Django >= 3.2
  • Python >= 3.8

License

MIT License - see LICENSE file for details

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Changelog

1.1.0 (2025-01-17)

  • Added custom imports support via Django settings and ModelAdmin attribute

1.0.0 (2025-07-17)

  • Initial release
  • Full Django ORM query support
  • Query history and favorites
  • Dark mode support
  • Collapsible interface

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_admin_query_executor-1.1.0-py3-none-any.whl (18.5 kB view details)

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for django_admin_query_executor-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b341a66cecf92ae58516bbb686a1c9ab52978bb411afb344c7b930c884ca1da7
MD5 8860ea3fa90e5cd5c9053fdabdb79030
BLAKE2b-256 912e60c034bbc71ec463bdd0fa266e8ed434b4011c772a212cbcea285efe1359

See more details on using hashes here.

Supported by

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