Django新手如何拆分表单字段在自定义设计页面渲染?
实现方法
Django表单支持单独渲染每个字段,你只需要替换掉原来的{{ form.as_table }},按你的页面结构手动调用对应字段即可。
基础字段拆分语法
- 字段标签:
{{ form.字段名.label }}会自动输出模型中定义的字段名(也支持自定义) - 输入控件:
{{ form.字段名 }}自动输出对应类型的输入框(文本框、下拉框、日期选择框等) - 错误提示:
{{ form.字段名.errors }}输出该字段的校验错误信息 - 字段帮助文本(如果有定义):
{{ form.字段名.help_text }}
适配你业务的模板示例
你可以按照你的页面设计调整布局、添加自定义class、嵌套任意HTML结构,示例如下:
{%extends 'base.html'%} {% block content %} <form action="" method="post"> {% csrf_token %} <!-- 全局非字段错误提示 --> {% if form.non_field_errors %} <div class="error-box"> {{ form.non_field_errors }} </div> {% endif %} <!-- 比如你设计的标题区域 --> <div class="form-group title-section"> <label for="{{ form.title.id_for_label }}">任务标题</label> {{ form.title }} {% if form.title.errors %} <span class="error-text">{{ form.title.errors.0 }}</span> {% endif %} </div> <!-- 比如你设计的内容区域 --> <div class="form-group content-section"> <label for="{{ form.text.id_for_label }}">任务详情</label> {{ form.text }} {% if form.text.errors %} <span class="error-text">{{ form.text.errors.0 }}</span> {% endif %} </div> <!-- 比如你设计的侧边栏区域 --> <div class="sidebar"> <!-- 创建页面才会显示status字段,更新页面因为fields没配置所以不会渲染,不会报错 --> {% if form.status %} <div class="form-group"> <label for="{{ form.status.id_for_label }}">任务状态</label> {{ form.status }} {% if form.status.errors %} <span class="error-text">{{ form.status.errors.0 }}</span> {% endif %} </div> {% endif %} <div class="form-group"> <label for="{{ form.endDate.id_for_label }}">截止日期</label> {{ form.endDate }} {% if form.endDate.errors %} <span class="error-text">{{ form.endDate.errors.0 }}</span> {% endif %} </div> </div> <!-- 你设计的按钮区域 --> <div class="form-actions"> <button type="submit" class="btn btn-primary">保存任务</button> <a href="{% url 'task:all' %}" class="btn btn-secondary">取消</a> </div> </form> {% endblock %}
可选:给输入框添加自定义类名
如果你需要给输入框加自定义CSS类(比如适配前端框架的样式类),有两种实现方式:
方式1:自定义ModelForm(推荐)
在app下新建forms.py,添加如下代码:
from django import forms from .models import Task class TaskForm(forms.ModelForm): class Meta: model = Task fields = ["title","text","status","endDate"] widgets = { 'title': forms.TextInput(attrs={'class': 'form-control'}), 'text': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}), 'status': forms.Select(attrs={'class': 'form-control'}), 'endDate': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), } class TaskUpdateForm(forms.ModelForm): class Meta: model = Task fields = ["title", "text", "endDate"] widgets = { 'title': forms.TextInput(attrs={'class': 'form-control'}), 'text': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}), 'endDate': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), }
然后修改views.py中的视图,把fields属性替换为form_class:
class TaskUpdateView(OwnerUpdateView): model = Task form_class = TaskUpdateForm class TaskCreateView(OwnerCreateView): model = Task form_class = TaskForm
方式2:在模板中直接添加属性
如果不想改Python代码,也可以在模板中直接给控件加属性:
{{ form.title.attrs.class = "form-control" }} {{ form.title }}
拆分之后你可以完全控制每个字段的位置、样式,直接嵌入你已经做好的HTML页面结构中即可。
内容的提问来源于stack exchange,提问作者Mont
相关产品推荐
相关产品推荐

