Alpine.js variables in Django Admin forms
Project description
django-form-alpine
django-form-alpine integrates Alpine.js into Django forms declaratively — you write Alpine directives directly in your widget attrs, and the library resolves which surrounding DOM element each directive should land on.
A Django Admin preset is included out of the box, so you get zero-config support for all standard admin containers. You can also define your own resolvers to use the library in any Django form, outside of the admin.
Installation
pip install django-form-alpine
Add django_form_alpine to INSTALLED_APPS:
INSTALLED_APPS = [
# ...
"django_form_alpine",
# ...
]
How it works
The library has two layers:
core.js— the engine. OnDOMContentLoadedit readswindow.DjangoFormAlpine.resolvers, iterates over all form inputs, and for each resolver it applies any matching prefixed attributes to the resolved container.admin.js— the Django Admin preset. Registers built-in resolvers for all standard admin containers (.form-row,fieldset,.field-box,.inline-related, etc.) intowindow.DjangoFormAlpineunless you supply your own.
Two mixins are provided:
| Mixin | Loads | Use when |
|---|---|---|
FormAlpineMixin |
core.js + alpine.js |
Any Django form with custom resolvers |
AdminAlpineMixin |
admin.js + core.js + alpine.js |
Django Admin (built-in resolvers included) |
Quick start
Django Admin
Inherit from AdminAlpineMixin in your ModelAdmin or admin Form:
from django.contrib import admin
from django_form_alpine import AdminAlpineMixin
from .models import MyModel
@admin.register(MyModel)
class MyModelAdmin(AdminAlpineMixin, admin.ModelAdmin):
pass
That's it — the admin preset resolvers are loaded automatically.
Any Django form
Use FormAlpineMixin and define your own resolvers (see Custom resolvers):
from django import forms
from django_form_alpine import FormAlpineMixin
class MyForm(FormAlpineMixin, forms.ModelForm):
class Meta:
model = MyModel
fields = "__all__"
Features
Synchronize state with x-add-model-data
Add x-add-model-data to a widget to automatically register the field in the form's x-data and bind it with x-model:
class MyForm(forms.ModelForm):
my_field = forms.CharField(
widget=forms.TextInput(attrs={
"x-add-model-data": "myFieldState"
})
)
This initializes myFieldState in the closest form[x-data] and sets x-model="myFieldState" on the input.
Prefixed directives
Apply Alpine.js directives to surrounding containers directly from widget attrs using the x-<resolver>-<directive> (or @<resolver>-<directive>) pattern.
Django Admin preset resolvers
| Prefix | Target container |
|---|---|
form-row |
Closest .form-row |
form-multiline |
Closest .form-multiline |
form |
Closest form |
fieldset |
Closest fieldset |
field-box |
Closest .field-box (falls back to label.parentElement, then el.parentElement) |
field-container |
Parent of the field box |
label |
Field's label (inside .flex-container or .form-row) |
errorlist |
.errorlist inside the field container |
help |
.help inside the field container |
inline-container |
tr.form-row or .inline-related |
nonfield-errorlist |
.errorlist.nonfield in tabular or stacked inlines |
option-label |
Closest label (for checkboxes and radios) |
Example: show/hide a form row
class MyForm(forms.ModelForm):
toggle = forms.BooleanField(
widget=forms.CheckboxInput(attrs={
"x-add-model-data": "showExtra"
})
)
extra_field = forms.CharField(
widget=forms.TextInput(attrs={
"x-form-row-show": "showExtra"
})
)
Inline forms with __row_prefix__
Use __row_prefix__ to namespace Alpine state keys per inline row, so each row has its own independent state:
class MyInlineForm(AdminAlpineMixin, forms.ModelForm): # or FormAlpineMixin with custom resolvers
my_field = forms.CharField(
widget=forms.TextInput(attrs={
"x-add-model-data": "__row_prefix__myField",
"x-field-box-show": "__row_prefix__otherField",
})
)
__row_prefix__ is resolved at runtime in this order:
- Container ID — ID of the closest
tr.form-rowor.inline-related, with dashes replaced by underscores (e.g.items_0). So__row_prefix__myField→items_0_myField. - Element
name— parsed with aprefix-numberpattern (e.g.items-0). The prefix is used as-is, preserving the dash. - Empty string —
__row_prefix__is simply removed if neither applies.
Custom resolvers
Use FormAlpineMixin and define your resolvers in a <script> tag before the form's scripts load:
<script>
window.DjangoFormAlpine = {
resolvers: {
"my-section": (el) => el.closest(".my-section"),
"my-label": (el) => el.closest(".my-label"),
},
};
</script>
Each resolver is a function (el) => HTMLElement | null where el is the form input element.
When you provide your own resolvers, the admin preset is not loaded. If you want both, set useAdminResolvers: true:
<script>
window.DjangoFormAlpine = {
useAdminResolvers: true,
resolvers: {
// Your custom resolver — merged on top of the admin ones
"my-section": (el) => el.closest(".my-section"),
},
};
</script>
Configuration
To use a custom Alpine.js bundle instead of the one included with the package:
# settings.py
django_form_alpine_JS_PATH = "path/to/your/custom-alpine.js"
Changelog
See CHANGELOG.md for full release notes.
Contributing
See CONTRIBUTING.md
License
This project is licensed under the MIT License - see the LICENSE file for details.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_form_alpine-0.0.2.tar.gz.
File metadata
- Download URL: django_form_alpine-0.0.2.tar.gz
- Upload date:
- Size: 32.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6d0ec242a783b779628766156baa802a7a171fc9607ab8cc94f974f4381fbd2
|
|
| MD5 |
ad790892b4701543a264b1f225d28d1b
|
|
| BLAKE2b-256 |
d452df4df1496e595838330cc1ba7f8107a478c527fcf11adedc4860981b2972
|
Provenance
The following attestation bundles were made for django_form_alpine-0.0.2.tar.gz:
Publisher:
release.yml on rodolvbg/django-form-alpine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_form_alpine-0.0.2.tar.gz -
Subject digest:
c6d0ec242a783b779628766156baa802a7a171fc9607ab8cc94f974f4381fbd2 - Sigstore transparency entry: 1185705687
- Sigstore integration time:
-
Permalink:
rodolvbg/django-form-alpine@9c1c0e79204939ea2525487ffc3aa79c3162dea9 -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/rodolvbg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9c1c0e79204939ea2525487ffc3aa79c3162dea9 -
Trigger Event:
release
-
Statement type:
File details
Details for the file django_form_alpine-0.0.2-py3-none-any.whl.
File metadata
- Download URL: django_form_alpine-0.0.2-py3-none-any.whl
- Upload date:
- Size: 29.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ba36c60d68d40c0c867749349458aa7ebdcbfb706d7320c9d639eccb5a70a09
|
|
| MD5 |
6c60e3f58d7079e6f5dab04ab678d057
|
|
| BLAKE2b-256 |
cbb713c3c1a37f62af27a74d70308acbe481748a6585865e151d96c4b258f889
|
Provenance
The following attestation bundles were made for django_form_alpine-0.0.2-py3-none-any.whl:
Publisher:
release.yml on rodolvbg/django-form-alpine
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_form_alpine-0.0.2-py3-none-any.whl -
Subject digest:
9ba36c60d68d40c0c867749349458aa7ebdcbfb706d7320c9d639eccb5a70a09 - Sigstore transparency entry: 1185705691
- Sigstore integration time:
-
Permalink:
rodolvbg/django-form-alpine@9c1c0e79204939ea2525487ffc3aa79c3162dea9 -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/rodolvbg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9c1c0e79204939ea2525487ffc3aa79c3162dea9 -
Trigger Event:
release
-
Statement type: