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.1.tar.gz (24.9 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.1-py3-none-any.whl (34.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: django_boosted-1.0.1.tar.gz
  • Upload date:
  • Size: 24.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_boosted-1.0.1.tar.gz
Algorithm Hash digest
SHA256 d50bd200e4eac998c25d0169b4a5aa0cc8ee396958ec5b6b8bd84207b4a60ab6
MD5 9e410cd98c60ed2b8ebfca1ea85e7eb4
BLAKE2b-256 b0e837e3eddf626642d893ba7224f7c047e6ba6c6e1bb624226c763e60d722d5

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_boosted-1.0.1.tar.gz:

Publisher: release.yml on octolo/django-boosted

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: django_boosted-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 34.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for django_boosted-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7682e4f32004433a826536f991659ec08002fab2f1096c5d824588417858240c
MD5 e3bf05fb0039d3f0385e051b3411725e
BLAKE2b-256 20215f7fddb3d0cf62e182a749c20a6984704526e6dbc27733f99b88a13befc4

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_boosted-1.0.1-py3-none-any.whl:

Publisher: release.yml on octolo/django-boosted

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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