Add simple dynamic interaction to the otherwise static django admin.
Project description
django-dynamic-admin-forms
Add simple interactions to the otherwise static django admin.
Installation
-
Install the package via pip:
pip install django-dynamic-admin-forms
or via pipenv:
pipenv install django-dynamic-admin-forms
-
Add the module to
INSTALLED_APPS
:INSTALLED_APPS = ( ..., 'dynamic_admin_forms', 'django.contrib.admin' ... )
Ensure that the
dynamic_admin_forms
comes before the defaultdjango.contrib.admin
in the list of installed apps, because otherwise the templates, which are overwritten bydynamic_admin_forms
won't be found. -
Ensure that the
dynamic_admin_forms
templates are found via usingAPP_DIRS
setting:TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'APP_DIRS': True, ... }, ]
-
Run
python manage.py collectstatic
to include this apps Javascript code in yoursettings.STATIC_ROOT
directory
Usage
-
Add the
dynamic_admin_forms.DynamicModelAdminMixin
to your admin classes -
In addition to the standard
fields
declaration, specify a list ofdynamic_fields
-
For each dynamic field, add a method
get_dynamic_{field_name}_field
to the admin- Input:
data: Dict[str, Any]
- the cleaned form data - Output:
queryset: Optional[Queryset]
- The values to select fromvalue: Any
- The value, the field should have (must be compatible to the field type)hidden: Bool
- True, if field should be hidden
- Input:
-
A rather non-sensical example:
from django.contrib import admin from .models import MyModel from dynamic_admin_forms.admin import DynamicModelAdminMixin @admin.register(MyModel) class MyModelAdmin(DynamicModelAdminMixin, admin.ModelAdmin): fields = ("name", "city") dynamic_fields = ("city",) def get_dynamic_city_field(self, data): # automatically choose first city that matches first letter of name name = data.get("name") if not name: queryset = City.objects.all() value = data.get("city") else: queryset = City.objects.filter(name__startswith=name[0]) value = queryset.first() hidden = not queryset.exists() return queryset, value, hidden
How it works
Whenever a dynamic form changes, an event handler makes a request to a special endpoint, which returns new HTML to swap
into the existing form. This new HTML is directly generated by django.contrib.admin
, so we only have to set the
outerHTML of the correct HTML elements to update the form.
Limitations
- does not work in conjunction with inlines
- does not validate that the selected value is really part of the original queryset
- if anybody can modify your DOM, they could potentially inject invalid values
- you have to write
Model.clean()
methods to guard against that
- only tested with Django 3.2
Changelog
- 0.1.5: Jazzmin "support"
- 0.1.4: README fixes
- 0.1.3: Change Demo-GIF hosting
- 0.1.2: README fixes
- 0.1.1: README fixes
- 0.1.0: Initial release
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django-dynamic-admin-forms-0.1.5.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | d6099abade7f6ab65c99593828c5c46431edb654f002e10e956b7e40b83c5417 |
|
MD5 | d78a46b96094837c0afccdbf6ba4c69f |
|
BLAKE2b-256 | 8d03bc97cda5f7661f81f1058bd42bad1ff51e6040d6b64652a0f7bcf3e65559 |
Hashes for django_dynamic_admin_forms-0.1.5-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8bdfe90f231f8587413980f699923ac401c8e54cfe49dfcf0c9d8297fb00c059 |
|
MD5 | 8b6aa78f13c4c71d63b94c8975eb3235 |
|
BLAKE2b-256 | 2e35d5336d373611303580b6e683041f6e5b8ce6fee3af575789e63430d79a20 |