Skip to main content

Reusable helpers to register custom Django admin views and object tools.

Project description

django-boosted

Lightweight helpers to extend Django’s admin with extra views, custom forms, and the matching UI affordances (object tools, permissions, standard responses).

Features

  • @admin_boost_object_view decorator – fetches the target object, checks permissions, and builds the default context before rendering your template.
  • AdminBoostMixin – registers the custom URLs, protects them with admin_site.admin_view, and injects extra object-tool buttons into the change form.
  • AuditMixin – adds created_by, updated_by, created_at, updated_at with automatic user tracking via middleware.
  • Additional templates – a change form template that renders the injected buttons plus a simple “Hello” view as a teaching aid.

Installation

pip install django-boosted

Quick start

# app/admin.py
from django.contrib import admin
from django_boosted.mixins import AdminBoostMixin
from django_boosted.decorators import admin_boost_object_view
from .models import Client


class ClientAdmin(AdminBoostMixin, admin.ModelAdmin):
    boost_views = ["hello_view"]
    change_form_template = "admin_boost/change_form.html"

    @admin_boost_object_view(label="Say hello", template_name="admin_boost/hello.html")
    def hello_view(self, request, obj):
        return {"message": f"Hello {obj}!"}


admin.site.register(Client, ClientAdmin)

Include the provided templates in your TEMPLATES["DIRS"] (or copy them to customize).

Using forms with ForeignKey widgets

The decorator can automatically apply admin widgets (ForeignKeyRawIdWidget or AutocompleteSelect) to your form fields, using the same logic as ModelAdmin.change_view():

# app/admin.py
from django import forms
from django.contrib import admin, messages
from django.shortcuts import redirect
from django_boosted.mixins import AdminBoostMixin
from django_boosted.decorators import admin_boost_object_view
from .models import Company

class SyncFullGroupForm(forms.Form):
    group = forms.ModelChoiceField(queryset=Company.objects.all())
    option = forms.ChoiceField(
        label="sync method",
        choices=[("method1", "Method 1"), ("method2", "Method 2")],
    )

class CompanyAdmin(AdminBoostMixin, admin.ModelAdmin):
    boost_views = ["sync_full_group_view"]
    change_form_template = "admin_boost/change_form.html"

    @admin_boost_object_view(
        label="Sync Full Group",
        template_name="admin/sync_full_group.html",
        form=SyncFullGroupForm,
        raw_id_fields=["group"],  # Automatically applies ForeignKeyRawIdWidget
    )
    def sync_full_group_view(self, request, obj, form):
        if request.method == "POST" and form.is_valid():
            # Process form...
            group = form.cleaned_data["group"]
            option = form.cleaned_data["option"]
            # ... your logic ...
            self.message_user(request, "Sync completed", messages.SUCCESS)
            return redirect(obj.admin_change_url)
        return {}  # Return additional context if needed

The decorator handles:

  • Widget application (respects raw_id_fields and autocomplete_fields)
  • Form validation on POST
  • Adding the form to the template context
  • Backward compatibility (if your view doesn't accept a form parameter, it won't be passed)

Audit (created_by / updated_by)

  1. Add CurrentUserMiddleware to MIDDLEWARE (after AuthenticationMiddleware):
MIDDLEWARE = [
    ...
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    ...
    "django_boosted.middleware.CurrentUserMiddleware",
]
  1. Use AuditMixin on your models:
from django.db import models
from django_boosted import AuditMixin

class Article(AuditMixin, models.Model):
    title = models.CharField(max_length=200)

The mixin automatically sets created_by on first save and updated_by on each save when a user is authenticated.

created_by and updated_by use AuditUserField: auto-filled with configurable concatenation. Default: ('pk', 'username') joined with _. Override audit_user_format and audit_user_separator on the model, or use the field directly:

# Via mixin
class Article(AuditMixin, models.Model):
    audit_user_format = ("pk", "email")
    audit_user_separator = "-"

# Or use AuditUserField standalone
from django_boosted import AuditUserField

class Log(models.Model):
    editor = AuditUserField(format_fields=("pk", "username"), mode="updated")

Settings:

  • DJANGO_BOOSTED_AUDIT_USER_FALLBACK — default value when no request user (migrations, commands, scripts). Example: "robot_octolo". If not set, default is None.
  • DJANGO_BOOSTED_AUDIT_USER_FORMAT_FIELDS — tuple of user attributes for the stored value. Default: ("pk", "username").
  • DJANGO_BOOSTED_AUDIT_USER_SEPARATOR — separator between format fields. Default: "_".

In templates or Python, created_by and updated_by return AuditUserValue (str subclass) with admin_url:

obj.created_by  # "42-johndoe"
obj.created_by.admin_url  # "/admin/auth/user/42/change/"

Development commands

Run everything via ./service.py dev <command> or python dev.py <command>:

Command Description
./service.py dev install-dev or python dev.py install-dev create the venv and install the package editable with dev extras.
./service.py dev lint or python dev.py lint run Ruff + Black in check mode.
./service.py dev format or python dev.py format apply Ruff --fix then Black.
./service.py dev test or python dev.py test run pytest (with pytest-django).
./service.py dev build or python dev.py build clean then build wheel + sdist.
./service.py quality security or python dev.py security Bandit + Safety + pip-audit.
./service.py dev help or python dev.py help list all commands.

License

MIT — see the LICENSE file. Contributions welcome!

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_boosted-1.0.0.tar.gz (25.0 kB view details)

Uploaded Source

Built Distribution

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

django_boosted-1.0.0-py3-none-any.whl (34.9 kB view details)

Uploaded Python 3

File details

Details for the file django_boosted-1.0.0.tar.gz.

File metadata

  • Download URL: django_boosted-1.0.0.tar.gz
  • Upload date:
  • Size: 25.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for django_boosted-1.0.0.tar.gz
Algorithm Hash digest
SHA256 0b46404488e7fbbf1de995177a38dc98fbf6512bbe6ed0048f7780d6a62d0dba
MD5 6e1f15b11fb4478b5025e035f8095d29
BLAKE2b-256 6f6127cf8b423bb1c90bf5e4686dd6a5f8eed4c9e357d7a880e864da957ba789

See more details on using hashes here.

File details

Details for the file django_boosted-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: django_boosted-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 34.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for django_boosted-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 763a943fec451267d73389c704cd7038cda828b8f1e98d7eee0132077725b512
MD5 b87827294e8523f9cb75c546a81ec539
BLAKE2b-256 a94128b23b524742a06348cd715def2a275df2529c03282a28208b35dde2beae

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