一键导入
django-glue-forms
Django Glue Alpine.js integration for reactive Django forms
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Django Glue Alpine.js integration for reactive Django forms
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | django-glue-forms |
| description | Django Glue Alpine.js integration for reactive Django forms |
Django Glue Forms provides seamless Alpine.js integration for Django forms, enabling reactive, two-way data binding between server-side Django forms and client-side JavaScript. It bridges the gap between Django's server-side validation and Alpine.js's reactive UI capabilities.
Note: Both approaches can be used together in the same form.
from django_glue.access.access import Access
# Permission hierarchy (lowest to highest)
Access.VIEW # Read-only access
Access.CHANGE # Read and modify access
Access.DELETE # Full access including delete
All glue objects are stored in Django session with:
Located in django_glue/templates/django_glue/form/field/:
| Template | Use Case | Django Field Type |
|---|---|---|
char_field.html | Text inputs | CharField |
email_field.html | Email inputs | EmailField |
password_field.html | Password inputs | CharField (password) |
number_field.html | Number inputs | IntegerField, FloatField |
date_field.html | Date inputs | DateField |
datetime_field.html | Datetime inputs | DateTimeField |
time_field.html | Time inputs | TimeField |
text_field.html | Textarea inputs | TextField |
select_field.html | Single select dropdowns | ChoiceField, ForeignKey |
multi_select_field.html | Multi-select dropdowns | ManyToManyField |
single_checkbox_field.html | Boolean checkboxes | BooleanField |
radio_field.html | Radio buttons | ChoiceField |
search_and_select_field.html | Searchable selects | ForeignKey |
color_field.html | Color pickers | ColorField |
telephone_field.html | Phone number inputs | CharField (phone) |
range_field.html | Range sliders | FloatField (range) |
decimal_field.html | Decimal inputs | DecimalField |
_base_file_field.html | File upload base | FileField |
single_file_field.html | Single file upload | FileField |
multi_file_field.html | Multiple file upload | FileField (multiple) |
_multi_checkbox_field.html | Multiple checkboxes | MultipleChoiceField |
All field templates extend base_field.html which handles:
dg.glue_model_object(request, 'company', company_instance, 'change')
What happens:
ModelObjectGlue object with model metadatacompany: new ModelObjectGlue('company')
What happens:
init() calls this.company.get(){% include 'django_glue/form/field/char_field.html' with glue_model_field='company.name' %}
What happens:
base_field.html) sets up Alpine.js data bindingx-model="value" binds to company.name.value<form method="post">
What happens:
cleaned_datashow_form_errors()View (app/company/views/form_views.py):
def _form_view(request: WSGIRequest, pk: int):
company = get_object_or_null_obj(models.Company, pk=pk)
dg.glue_model_object(request, 'company', company, 'view')
if request.method == 'POST':
form = forms.CompanyForm(request.POST, instance=company)
if form.is_valid():
company, _ = company.services.save_model_obj(**form.cleaned_data)
add_form_activity(company, pk, request.user)
return redirect(return_url)
show_form_errors(request, form)
else:
form = forms.CompanyForm(instance=company)
return portal_views.form_view(
request,
form=form,
obj=company,
template='company/page/form_page.html',
)
Template (templates/company/form/form.html):
<form method="post" x-data="{
async init() {
await this.company.get()
},
company: new ModelObjectGlue('company')
}">
{% csrf_token %}
{% include 'django_glue/form/field/char_field.html' with glue_model_field='company.name' %}
{% include 'django_glue/form/field/text_field.html' with glue_model_field='company.description' %}
{% include 'django_spire/contrib/form/button/form_submit_button.html' %}
</form>
There are two ways to bind form fields with Django Glue:
Both approaches use the same field templates. The difference is how you initialize the data in x-data.
| Field Type | Use Case |
|---|---|
GlueCharField | Text inputs |
GlueIntegerField | Integer inputs with min/max/step |
GlueDecimalField | Decimal inputs with step precision |
GlueBooleanField | Boolean checkboxes (Yes/No choices) |
GlueDateField | Date inputs with min/max |
All Glue fields support these properties:
| Property | Type | Description |
|---|---|---|
value | any | Current field value |
label | string | Field label text |
choices | array | Array of [value, label] pairs |
required | boolean | Make field required |
hidden | boolean | Hide field from view |
read_only | boolean | Make field read-only |
disabled | boolean | Disable field input |
autofocus | boolean | Auto-focus on field |
help_text | string | Help text tooltip |
set_attribute(name, value) | method | Set custom HTML attribute |
remove_attribute(name) | method | Remove HTML attribute |
hide_label() | method | Hide label visually |
show_label() | method | Show label |
Initialize any field type directly in Alpine.js x-data:
<form method="post" x-data="{
async init() {
// Set initial value
this.partner_field.value = {{ partner.pk|default_if_none:'null' }}
// Load choices dynamically
this.partner_field.choices = await this.partners.to_choices()
// Modify field properties
this.partner_field.label = 'Partner'
this.partner_field.required = true
// Watch for changes
this.$watch('partner_field.value', async () => {
this.agreement_field.choices = await this.get_agreements.call({
'partner_id': this.partner_field.value
})
})
},
// Initialize standalone fields
partner_field: new GlueCharField('partner'),
agreement_field: new GlueCharField('agreement'),
// Supporting objects
partners: new QuerySetGlue('partners'),
get_agreements: new FunctionGlue('get_agreements'),
}">
{% csrf_token %}
<!-- Use glue_field parameter for standalone fields -->
{% include 'django_glue/form/field/search_and_select_field.html' with glue_field='partner_field' %}
{% include 'django_glue/form/field/search_and_select_field.html' with glue_field='agreement_field' %}
<button class="btn btn-app-primary">Submit</button>
</form>
You can use ModelObjectGlue and standalone fields in the same form:
<form method="post" x-data="{
async init() {
// Load model object
await this.scope_of_work.get()
// Initialize standalone fields
this.partner_field.choices = await this.partners.to_choices()
},
// Model-backed fields
scope_of_work: new ModelObjectGlue('scope_of_work'),
// Standalone fields
partner_field: new GlueCharField('partner'),
// Supporting objects
partners: new QuerySetGlue('partners'),
}">
{% csrf_token %}
<!-- Model field (uses glue_model_field) -->
{% include 'django_glue/form/field/char_field.html' with glue_model_field='scope_of_work.name' %}
<!-- Standalone field (uses glue_field) -->
{% include 'django_glue/form/field/search_and_select_field.html' with glue_field='partner_field' %}
<button class="btn btn-app-primary">Submit</button>
</form>
Key Points:
glue_model_field='object.field'glue_field='field_name'x-data with new Glue*Field('name')# Only include specific fields
dg.glue_model_object(request, 'obj', instance, fields=('name', 'email'))
# Exclude specific fields
dg.glue_model_object(request, 'obj', instance, exclude=('password', 'secret'))
# Include all except some
dg.glue_model_object(request, 'obj', instance,
fields=('__all__',),
exclude=('internal_notes',))
def my_view(request):
obj = MyModel.objects.get(pk=1)
dg.glue_model_object(request, 'obj', obj, methods=('get_full_name',))
# In template
<div x-text="company.get_full_name()"></div>
Always exclude sensitive data:
dg.glue_model_object(
request,
'user',
user_instance,
exclude=('password', 'secret_key', 'internal_notes')
)
When reviewing Django Glue Forms code, verify the following:
dg.glue_model_object() before renderingunique_name parameter matches between server and client codeasync init() with .get() call{% csrf_token %}glue_model_field for all ModelObjectGlue fieldsBest practices for writing Django tests (updated template)
GlueFetchHelper patterns for making AJAX calls in templates
Advanced seeding patterns for linking specific foreign keys
Apply DjangoSpire app CSS variables in templates instead of inline styles
Django URL configuration patterns, namespaces, and nested structure conventions
Best practices for AI bots, prompts, and intel in scope_of_work