Form
1.models表单定义:
from django import forms # 导入表单模块 from django.core.exceptions import ValidationError class RegisterForm(forms.Form): # 自定义表单类,并继承forms.Form email = forms.EmailField(widget=forms.EmailInput( attrs={"class": "form-control"})) username = forms.CharField(min_length=4, max_length=12, widget=forms.TextInput( attrs={"class": "form-control"})) password = forms.CharField(min_length=6, widget=forms.PasswordInput( attrs={"class": "form-control"})) password2 = forms.CharField(min_length=6, widget=forms.PasswordInput( attrs={"class": "form-control"})) valid_code = forms.CharField(widget=forms.TextInput( attrs={"class": "form-control"})) def __init__(self, request, *args, **kwargs): # 如果需要额外接收参数,要重写构造器函数 # 这里额外接收一个参数,用于从request.sesssion中提取之前保存的验证码 super(RegisterForm,self).__init__(*args, **kwargs) self.request = request # 自定义方法(局部钩子),密码必须包含字母和数字 def clean_password(self): if self.cleaned_data.get('password').isdigit() or self.cleaned_data.get('password').isalpha(): raise ValidationError('密码必须包含数字和字母') else: return self.cleaned_data['password'] def clean_valid_code(self): # 检验验证码正确;之前生成的验证码保存在了了session中 if self.cleaned_data.get('valid_code').upper() == self.request.session.get('valid_code'): return self.cleaned_data['valid_code'] else: raise ValidationError('验证码不正确') # 自定义方法(全局钩子, 检验两个字段),检验两次密码一致; def clean(self): if self.cleaned_data.get('password') != self.cleaned_data.get('password2'): raise ValidationError('密码不一致') else: return self.cleaned_data # 注意,上面的字典取值用get, 因为假如在clean_password中判断失败,那么没有返回值,最下面的clean方法直接取值就会失败s
说明:
min_length,max_length=12定义字段字符长度
error_messages={"requied":["必填"]}自定义错误信息
widget参数用来指定字段的类型和属性
clean是验证函数,分为局部钩子和全局钩子,局部钩子先于全局钩子的运行;局部钩子clean_field用来验证单个字段,全局钩子clean用于验证两个字段
clean验证函数必须有返回值
2.模板渲染models表单
# 实例化表单对象; 因为重写了init方法,这里要额外接收request form_obj = RegisterForm(request)
<form action="{% url 'register' %}" method="post" id="register"> {% csrf_token %} <div class="form-group"> <label for="id_email">邮箱 </label><span class="error-info"></span> {{ form_obj.email }} <!-- span 标签用于放置错误信息 --> </div> ...... <p class="reg-button"> <button type="submit" class="btn btn-primary btn-block"> 注册 </button> </p> </form>
说明:<form>{{form_obj.as_p}}</form>也可以生成整个表单,但是自定义效果差
3.验证提交的表单
# 传入request.POST,实例化表单对象用于户验证和提取数据 form_obj = RegisterForm(request, request.POST) # 方法: form_obj.is_valid() # 根据字段属性和验证函数进行校验 form.cleaned_data.get(field) # 校验OK,提取数据 form.errors # 错误信息:{field:[error_info], field:[],...}
4.根据需求对用户提交的数据进行相应的操作
ModelForm
ModelForm对用户提交的数据有验证功能,但比Form要简单的多
from django.forms import ModelForm # 导入ModelForm
class UserModelForm(ModelForm):
class Meta:
model=models.UserInfo
fields="__all__"
labels={
'username':'用户名',
'password':'密码',
'nickname':'昵称',
'email':'邮箱',
'roles':'角色'
}
说明:
1.model:对应得表名
2.fields:选择字段列表,'__all__'是选择所有字段
3.exclude:排除字段列表
4.widgets:插件列表
5.labels:前端显示字段名
6.error_messages:自定义错误提示
7.localized_field:本地化,如:根据不同时区显示数据
数据库中 2016-12-27 04:10:57 setting中的配置 TIME_ZONE = 'Asia/Shanghai' USE_TZ = True 则显示: 2016-12-27 12:10:57
除了这些参数,ModelForm同样可以定义局部钩子和全局钩子
2.实例化表单对象,传入模板,同Form
model_form = UserInfoModelForm() return render(request,"login.html",{"model_form":model_form})
3.验证提交的表单
model_form = UserInfoModelForm(request.POST) if model_form.is_valid(): model_form.save()
4.如果是修改记录,则需要传入记录对象
model_form = UserInfoModelForm(instance=user_obj) model_form = UserInfoModelForm(request.POST, instance=user_obj) if model_form.is_valid(): model_form.save()