A simple utils for Django FormField
将form_field_utils包复制到项目文件夹下,并将form_field_utils添加到INSTALLED_APPS中。
todo: 通过setup.py安装
- 声明内层子Form。
from django import forms
class InnerForm(forms.Form):
field_0 = forms.CharField(max_length=100)- 声明外层Form,通过
FormField.Fields.FormField声明指向内层Form的from-field。
from formfiled.forms import FormFieldSupportMixin
from formfield.fields import FormField
class OuterForm(FormFieldSupportMixin, forms.Form):
field_outer = forms.CharField(max_length=100)
formfield = FormField(InnerForm)-
将View中实例化外层Form,并且将外层Form实例传入template context。
-
在template中对外层Form实例进行渲染。
{{ form.as_table}}
内层Form可以是Django ModelForm。
目前仅支持将
reverse OneToOneRel类型的Field设置为ModelFormField。
- 声明Django Model。
from django.db import models
class Order(models.Model):
name = models.CharField('订单名', max_length=100)
class Contract(models.Model):
serial_no = models.CharField('合同号', max_length=100)
order = models.OneToOneField(Order, on_delete=models.CASCADE)- 声明内层ModelForm
from django import forms
class ContractModelForm(forms.ModelForm):
class Meta:
model = Contract
fields = '__all__'- 声明外层ModelForm。
from formfield.forms import ModelFormFieldSupportMixin
from formfield.fields import ModelFormField
class OrderModelForm(ModelFormFieldSupportMixin, forms.ModelForm):
contract = ModelFormField(ContractModelForm)
class Meta:
model = Order
fields = '__all__'-
类似于Simple FormField的使用,在View中生成外层Form的实例传入template context,并在template中对Form实例进行渲染。
-
在View中对外成Form实例调用
save()方法,能够保存外层对象实例以及内层对象实例,并正确关联两者关系。
title选项用于指定FormField的标题,使得能够在渲染的时候打印。
默认title选项为None。
class OrdereModelForm(ModelFormFieldSupportMixin, forms.ModelForm):
contract = ModelFormField(
ContractModelForm,
title='关联合同'
)通过prefix选项,能够指定内层Form的prefix属性,以避免内外层Form在HTML表单中name属性名和id属性名冲突。
class OrdereModelForm(ModelFormFieldSupportMixin, forms.ModelForm):
contract = ModelFormField(
ContractModelForm,
prefix='contract'
)如果using_template为False,在template渲染FormField实例时({{ form_field }})会简单的调用内层form.as_table()方法。
如果using_template为True,则会按照内层FormFieldtemplate_name指定的template对内层Form实例进行渲染。
using_template默认为False。
当using_template为True的情况下,会根据template_name指定的template对内层Form对象进行渲染。
如果没有指定template_name,django-formfield-utils会使用自带的template对内层Form对象进行渲染。
class OrdereModelForm(ModelFormFieldSupportMixin, forms.ModelForm):
contract = ModelFormField(
ContractModelForm,
using_template=True,
template_name='path/to/template'
)简易的外层Form template代码示例如下:
{# simple template code of rendering outer form #}
{% load formfield_widget %}
{% for field in form %}
{% if field|is_formfield %}
{# just call __str__() method of formfield #}
{# so that can using template_name specified template #}
{# to render the inner form of the formfield #}
{{ field }}
{% else %}
{# render regular field here #}
{% endif %}
{% endfor %}
这里使用了django-formfield-utils自带的formfield_field.is_formfield filter,
在template中判断一个field是否是FormField。
todo: 增加设定全局FormField template的功能