Django表单overview
表单 is Webapplicationin用于收集user输入 important component. Djangoproviding了强 big 表单processingfunctions, including表单class定义, 表单verification, 表单渲染etc..
提示
Django 表单system可以helpingDevelopment者 fast 速creationsecurity, reliable 表单, 避免重复writingHTML表单 and verification逻辑.
表单class
in Djangoin, 表单 is throughPythonclass来定义 , inheritance自django.forms.Formclass.
creation表单class
# blog/forms.py
from django import forms
class CommentForm(forms.Form):
name = forms.CharField(label='姓名', max_length=100)
email = forms.EmailField(label='邮箱')
content = forms.CharField(label='评论 in 容', widget=forms.Textarea)
# 自定义verificationmethod
def clean_name(self):
name = self.cleaned_data.get('name')
if len(name) < 2:
raise forms.ValidationError('姓名 long 度不能 few 于2个字符')
return name
常用表单字段class型
- CharField: 文本输入框, 用于接收 short 文本.
- TextField: many 行文本输入框, 用于接收 long 文本.
- EmailField: 邮箱输入框, 会自动verification邮箱格式.
- URLField: URL输入框, 会自动verificationURL格式.
- IntegerField: 整数输入框.
- FloatField: 浮点数输入框.
- DecimalField: 十进制 small 数输入框.
- BooleanField: 复选框, 用于接收boolean值.
- DateField: 日期输入框.
- DateTimeField: 日期时间输入框.
- ChoiceField: under 拉选择框, 用于 from 预定义选项in选择.
- MultipleChoiceField: many 选框, 用于 from 预定义选项in选择 many 个.
- FileField: file on 传字段.
- ImageField: graph片 on 传字段, 会自动verificationgraph片格式.
表单字段选项
- label: 表单字段 tag文本.
- required: is 否 for 必填字段, 默认 for True.
- max_length: 最 big long 度.
- min_length: 最 small long 度.
- initial: 初始值.
- help_text: helping文本, 显示 in 字段 under 方.
- widget: 表单字段 HTML部件, 用于自定义字段 渲染方式.
- validators: 自定义verification器list.
in 视graphinusing表单
in 视graphin, 需要creation表单instance, 并processing表单 submitting and verification.
# blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import BlogPost, Comment
from .forms import CommentForm
def post_detail(request, pk):
post = get_object_or_404(BlogPost, pk=pk)
comments = post.comments.all()
if request.method == 'POST':
# creation表单instance并填充data
form = CommentForm(request.POST)
if form.is_valid():
# 获取verification after data
cleaned_data = form.cleaned_data
# creation评论object
comment = Comment(
post=post,
name=cleaned_data['name'],
email=cleaned_data['email'],
content=cleaned_data['content']
)
comment.save()
# 重定向 to 当 before 页面, 避免表单重复submitting
return redirect('post_detail', pk=pk)
else:
# creation空表单instance
form = CommentForm()
return render(request, 'blog/post_detail.html', {
'post': post,
'comments': comments,
'form': form
})
in 模板in渲染表单
Djangoproviding了 many 种方式 in 模板in渲染表单.
自动渲染表单
<!-- 渲染整个表单 -->
<form method="post">
{% csrf_token %}
{{ form.as_p }} <!-- 每个字段serving asptag -->
<!-- other渲染方式:
{{ form.as_table }} <!-- 每个字段serving astable行 -->
{{ form.as_ul }} <!-- 每个字段serving asullist项 -->
-->
<button type="submit">submitting评论</button>
</form>
手动渲染表单字段
<form method="post">
{% csrf_token %}
<div class="form-group">
<label for="{{ form.name.id_for_label }}">{{ form.name.label }}</label>
{{ form.name }} <!-- 渲染单个字段 -->
{% if form.name.errors %}
<div class="error">{{ form.name.errors }}</div>
{% endif %}
<small class="help-text">{{ form.name.help_text }}</small>
</div>
<div class="form-group">
<label for="{{ form.email.id_for_label }}">{{ form.email.label }}</label>
{{ form.email }}
{% if form.email.errors %}
<div class="error">{{ form.email.errors }}</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.content.id_for_label }}">{{ form.content.label }}</label>
{{ form.content }}
{% if form.content.errors %}
<div class="error">{{ form.content.errors }}</div>
{% endif %}
</div>
<button type="submit">submitting评论</button>
</form>
表单errorprocessing
<!-- 显示表单 非字段error -->
{% if form.non_field_errors %}
<div class="error">{{ form.non_field_errors }}</div>
{% endif %}
ModelForm
ModelForm is Djangoproviding 一个强 big functions, 它可以根据model自动生成表单.
creationModelForm
# blog/forms.py
from django import forms
from .models import BlogPost
class BlogPostForm(forms.ModelForm):
class Meta:
model = BlogPost
fields = ['title', 'content', 'is_published'] # 指定要package含 字段
# or 者排除某些字段
# exclude = ['pub_date', 'update_date']
# 自定义字段tag and helping文本
labels = {
'title': '文章标题',
'content': '文章 in 容',
'is_published': ' is 否release'
}
help_texts = {
'title': '请输入文章标题',
'content': '请输入文章 in 容',
'is_published': '勾选表示release这篇文章'
}
# 自定义widget
widgets = {
'content': forms.Textarea(attrs={'rows': 10, 'cols': 80})
}
in 视graphinusingModelForm
# blog/views.py
from django.shortcuts import render, redirect
from .forms import BlogPostForm
def create_post(request):
if request.method == 'POST':
form = BlogPostForm(request.POST)
if form.is_valid():
# 保存表单data to datalibrary
form.save()
return redirect('post_list')
else:
form = BlogPostForm()
return render(request, 'blog/create_post.html', {'form': form})
# update文章
def update_post(request, pk):
post = get_object_or_404(BlogPost, pk=pk)
if request.method == 'POST':
form = BlogPostForm(request.POST, instance=post) # 传入instanceparameter表示update现 has object
if form.is_valid():
form.save()
return redirect('post_detail', pk=pk)
else:
form = BlogPostForm(instance=post) # 传入instanceparameter表示using现 has object data填充表单
return render(request, 'blog/update_post.html', {'form': form, 'post': post})
ModelForm模板
<!-- blog/templates/blog/create_post.html -->
{% extends 'blog/base.html' %}
{% block title %}creation文章{% endblock %}
{% block content %}
<h1>creation new 文章</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">creation文章</button>
</form>
{% endblock %}
表单verification
Django表单systemproviding了强 big verificationfunctions, including字段级verification and 表单级verification.
字段级verification
through in 表单classin定义clean_字段名method来implementation字段级verification:
def clean_email(self):
email = self.cleaned_data.get('email')
if '@example.com' in email:
raise forms.ValidationError('不允许usingexample.com邮箱')
return email
表单级verification
through重写表单class cleanmethod来implementation表单级verification:
def clean(self):
cleaned_data = super().clean()
password1 = cleaned_data.get('password1')
password2 = cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise forms.ValidationError('两次输入 password不一致')
return cleaned_data
表单样式定制
可以through自定义widget attrsproperty来添加CSSclass and otherHTMLproperty:
# 方式1: in 表单classin定义
class CommentForm(forms.Form):
name = forms.CharField(
label='姓名',
max_length=100,
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入姓名'})
)
# other字段...
# 方式2: in 视graphin动态添加
form = CommentForm()
form.fields['name'].widget.attrs.update({'class': 'form-control'})
form.fields['email'].widget.attrs.update({'class': 'form-control'})
form.fields['content'].widget.attrs.update({'class': 'form-control', 'rows': 5})
练习 1: creation评论表单
- in blogapplicationincreationCommentmodel, package含name, email, content, post ( out 键) , created_at字段.
- creationCommentForm表单class, 用于submitting评论.
- in post_detail视graphin添加评论processing逻辑.
- in post_detail.html模板in添加评论表单.
- test评论functions.
练习 2: creation文章management表单
- creationBlogPostForm ModelForm, 用于creation and update文章.
- creationcreate_post and update_post视graph.
- creation for 应 模板.
- test文章 creation and updatefunctions.