WEB框架Django之Form组件
Django的Form主要具有一下几大功能:
- 生成HTML标签
- 验证用户数据(显示错误信息)
- HTML Form提交保留上次提交数据
- 初始化页面显示内容
一 通过form实现校验字段功能
模型:models.py
class UserInfo(models.Model):
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=32)
email = models.EmaillField()
tel = models.CharField(max_length=32)
模板:register.html
<form action="", method="post">
<p>用户名 <input type="text" name="username"></p>
<p>密码<input type="password" name="password"></p>
<p>确认密码<input type="password" name="repwd"></p>
<p>邮箱<input type="text" name="email"></p>
<p>手机号<input type="text" name="tel"></p>
<input type="submit">
{% csrf_token %}
</form>
二 通过form组件对模板进行渲染
form校验组件
from django import forms
class UserForm(forms.Form):
username = forms.CharField(min_length=4)
password = forms.CharField(min_length=4)
repwd = forms.CharField(min_length=4)
email = forms.EmailField()
tel = forms.CharField
视图函数
def register(req):
if req.method == 'POST':
# form = UserForm({'name':'cs', 'email': '123@qq.com', 'xxx':'harry'})
form = UserForm(req.POST) # 注意form表单的name属性值应该与forms组件字段名称一致
print(form.is_valid()) # 返回布尔值
if form.is_valid():
print(form.cleaned_data) # {"name":'cs", "email:'123@qq.com'}
else:
print(form.cleaned_data)
print(form.errors) # {"name":["......"]}
return HttpResponse('ok')
'''
if 所有的字段校验成功,则form.cleaned_data以一个字典的形式存放所有校验通过的数据
'''
return render(req, "register.html")
form组件在模板中渲染
<form class="col-md-4 form-group" action="",method="post">
<p>
用户名 {{ form.username }}
</p>
<p>
密码 {{ form.password }}
</p>
<p>
确认密码 {{ form.repwd }}
</p>
<p>
email {{ form.email }}
</p>
<p>
手机号 {{ form.tel }}
</p>
</form>
方式一
<form class="col-md-4 form-group" action="",method="post">
{% csrf_token %}
{% for filed in form %}
<p>
<lable>{{ filed.label }}</lable>
{{ filed }}
</p>
{% endfor %}
</form>
方式二
展示错误信息
<form class="col-md-6" action="" method="post" novalidate>
{% csrf_token %}
{% for filed in form %}
<p>
<lable>{{ filed.label }}</lable>
{{ filed }} <span>{{ filed.errors.0 }}</span>
</p>
{% endfor %}
<input type="submit">
</form>
三 form组件的配置参数
Filed参数
required=Ture 是否必填
widget=None HTNL插件
label=None 用于生成Label标签显示内容
initial=None 初始值
help_text='' 帮助信息(在标签旁边显示)
error_messages=None 错误信息{'required':'不能为空’, 'invalid':'格式错误’}
show_hidden_initial=False 是否在当前插件后再加一个隐藏的具有默认值的插件(可用于两次输入是否一致)
validators=[], 自定义验证规则
localize=False 是否支持本地化
disabled=False 是否可以编辑
label_suffix=None Lable内容后缀 CharField(Field)
max_length=None 最大长度
min_length=None 最小长度
strip=True 是否移除用户输入空白 IntergerField(Field)
max_value = None 最大值
min_value = None 最小值 DecimalField(IntergerField)
max_value=None 最大值
min_value=None 最小值
max_digits=None 总长度
decimal_places=None 小数位长度 BaseTemporalField(Field)
input_forats=None 时间格式化 DateField(BaseTemporalField) 格式:2015-09-01
TimeField(BaseTemporalField) 格式:11:12
DateTimeField(BaseTemporalField) 格式:2015-09-01 11:12 RegexField(charField)
regex, 自定义正则表达式
max_length=None, 最大长度
min_length=None, 最小长度
error_message=None {"invalid":"..."} FileField(Field)
allow_empty_file=False 是否允许空文件 ChoiceField(Field)
choices=(), 选项,如:choices = ((0,'上海’),(1,,'北京')
required=True 是否必填
widget=None 插件,默认select插件
label=None Label内容
initial=None 初始值
help_text='', 帮助提示 TypeChoiceField(ChoiceField)
coerce = lambda val: val 对选中的值进行一次转换
empty_value = '' 空的默认值 ComboFiel(Field)
fields=() 使用多个验证,如下:即验证最大程度20,又验证邮箱格式
fields.ComboField(fields=[fields.CharField(max_length=20),fields.EmailField(),] GenericIPAddressField
protocol='both', both,ipv4,ipv6支持的IP格式
unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.0.2.1 可以解析为192.0.0.2.1 SlugField(CharField) 数字,字母,下划线,减号(连接符)
在form中使用组件
from django.core.exceptions import NON_FIELD_ERRORS,ValidationError
class UserForm(forms.Form):
username = forms.CharField(min_length=2, label='用户名',
error_messages={"required": "该字段不能为空"},
widget= widgets.TextInput(attrs={'class':"form-control"}))
password = forms.CharField(min_length=4,
label='密码',
widget=widgets.PasswordInput(attrs={'class':"form-control"}))
repwd = forms.CharField(min_length=4,
label='重复密码',
widget= widgets.TextInput(attrs={'class':"form-control"}))
email = forms.EmailField(label='邮箱',
error_messages={"required": "该字段不能为空", "invalid":"格式输入错误"},
widget= widgets.TextInput(attrs={'class': "form-control"}))
tel = forms.CharField(label="电话号码",
error_messages={"required": "该字段不能为空"},
widget=widgets.TextInput(attrs={'class': "form-control"})) def clean_username(self):
val = self.cleaned_data.get("username") # 获取输入的名字
ret = UserInfo.objects.filter(name=val) # 从数据库中查询是否有该用户存在if not ret:
return val
else:
raise ValidationError("该用户已注册") def clean_tel(self):
var = self.cleaned_data.get("tel")
if len(var) == 11:
return var
else:
raise ValidationError("手机号码必须为11位!") def clean(self):
pwd = self.cleaned_data.get("password")
r_pwd = self.cleaned_data.get("repwd")
if pwd and r_pwd:
if pwd == r_pwd:
return self.cleaned_data
else:
raise ValidationError('两次密码不一致')
else:
return self.cleaned_data
在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段 ***获取的值无法实时更新***,那么需要自定义构造方法从而达到此目的。
方式一:
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator class MyForm(Form): user = fields.ChoiceField(
# choices=((1, '上海'), (2, '北京'),),
initial=2,
widget=widgets.Select
) def __init__(self, *args, **kwargs):
super(MyForm,self).__init__(*args, **kwargs)
# self.fields['user'].widget.choices = ((1, '上海'), (2, '北京'),)
# 或
self.fields['user'].widget.choices = models.Classes.objects.all().value_list('id','caption')
方式二:
使用django提供的ModelChoiceField和ModelMultipleChoiceField字段来实现
from django import forms
from django.forms import fields
from django.forms import widgets
from django.forms import models as form_model
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator class FInfo(forms.Form):
authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())
# authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())
四 自定义验证规则
方式一 使用字段钩子或者全局钩子
from django.core.exceptions import NON_FIELD_ERRORS,ValidationError
class UserForm(forms.Form):
username = forms.CharField(min_length=2,
label='用户名',
error_messages={"required": "该字段不能为空"},
widget=widgets.TextInput(attrs={'class':"form-control"}))
password = forms.CharField(min_length=4,
label='密码',
widget=widgets.PasswordInput(attrs={'class':"form-control"}))
repwd = forms.CharField(min_length=4,
label='重复密码',
widget= widgets.TextInput(attrs={'class':"form-control"}))
email = forms.EmailField(label='邮箱',
error_messages={"required": "该字段不能为空", "invalid":"格式输入错误"},
widget=widgets.TextInput(attrs={'class': "form-control"}))
tel = forms.CharField(label="电话号码",
error_messages={"required": "该字段不能为空"},
widget=widgets.TextInput(attrs={'class': "form-control"}))
def clean_username(self):
val = self.cleaned_data.get("username") # 获取输入的名字
ret = UserInfo.objects.filter(name=val) # 从数据库中查询是否有该用户存在if not ret:
return val
else:
raise ValidationError("该用户已注册") def clean_tel(self):
var = self.cleaned_data.get("tel")
if len(var) == 11:
return var
else:
raise ValidationError("手机号码必须为11位!") def clean(self):
pwd = self.cleaned_data.get("password")
r_pwd = self.cleaned_data.get("repwd")
if pwd and r_pwd:
if pwd == r_pwd:
return self.cleaned_data
else:
raise ValidationError('两次密码不一致')
else:
return self.cleaned_data
方式二 使用validators参数进行正则表达式匹配
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator class MyForm(Form):
user = fields.CharField(
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
)
通过正则表达式验证IP地址以及端口号
ipaddr_validate="^((?:(2[0-4]\d)|(25[0-5])|([01]?\d\d?))\.){3}(?:(2[0-4]\d)|(255[0-5])|([01]?\d\d?))$"
port_validate='^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$'
from django.forms import Form,fields
from django.forms import widgets,forms
import re
ipaddr_validate="^((?:(2[0-4]\d)|(25[0-5])|([01]?\d\d?))\.){3}(?:(2[0-4]\d)|(255[0-5])|([01]?\d\d?))$"
port_validate='^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$'
class dbinfo_create(Form):
data_mode_type=fields.CharField(required=True,error_messages={'required':'数据库模型不能为空.'})
database_type=fields.CharField(required=True,error_messages={'required':'数据库类型不能为空'})
host=fields.RegexField(ipaddr_validate,required=True,error_messages={'required':'IP不能为空','invalid':'不合法的IP地址'})
port=fields.RegexField(port_validate,required=True,error_messages={'required':'端口不能为空.','invalid':'端口无效'})
# instance_nikename=fields.CharField(max_length=20,error_messages={'required':'端口不能为空.',"max_length":"标题不能超过20个字"})
db_business=fields.CharField(required=True,error_messages={'required':'请说明所属业务线'})
DBA=fields.CharField(required=True,error_messages={'required':'请说明DBA'})
responsible_person=fields.CharField(required=True, error_messages={'required':'请选择相关责任人!'})
五 通过Ajax提交并验证表单
<form id="form">
<div class="form-group">
<p style="font-size: 26px; color: #337ab7">注册新用户</p>
<p><span id="summary-error"></span></p>
{% csrf_token %}
<p>
<span>用户名:</span>{{ form_obj.username }}
<span class="pull-right"></span>
</p> <p>
<span>密码:</span>{{ form_obj.password }}
<span class="pull-right"></span>
</p> <p>
<span>确认密码:</span>{{ form_obj.re_pwd }}
<span class="pull-right"></span>
</p>
<div class="row">
<div class="col-md-10">
<p>
Emil:{{ form_obj.email }}
<span class="pull-right"></span>
</p>
</div> <p class="col-md-2">
<button class="pull-right btn-primary btn" style="margin-top: 18px" id="get_email_code">获取验证码</button>
</p>
</div> <p>
<span>验证码</span>{{ form_obj.check_code }}
<span class="pull-right"></span>
</p> <label for="avatar">
<span>上传头像</span>
<img id="avatar_img" width="80" height="80" src="/media/avatar/default.jpg" style="margin-left: 10px">
</label>
<input type="file" id="avatar" style="display: none">
<div>
<input type="button" id='submit_info' class="btn-primary btn pull-right" value="提交">
</div>
</div>
</form>
HTML
function bindSubmit() {
$('#submit_info').click(function () {
$("#form p").removeClass('has-error');
$(".errors").html('');
var subData = new FormData();
var request_data = $('#form').serializeArray();
$.each(request_data, function (index, data) {
subData.append(data.name, data.value);
});
subData.append("avatar", $('#avatar')[0].files[0]);
subData.append('csrfmiddlewaretoken', $("[name='csrfmiddlewaretoken']").val());
$.ajax({
url: "/register/",
type: "post",
processData: false,
contentType: false,
data: subData,
dataType: 'json',
success: function (data) {
console.log(data.error_msg);
if (!data.state) {
if (data.summary_error) {
$('#summary-error').html(data.summary_error)
}
$.each(data.error_msg, function (field, msg) {
if (field == "__all__") {
$('#summary-error').html(msg[0]).parent().addClass("has-error")
}
$('#id_' + field).next().html(msg[0]).addClass('errors').parent().addClass('has-error')
})
} else {
console.log(123);
location.href = '/index/'
}
}
})
})
}
JS
class RegisterForm(forms.Form):
'''
注册form表单校验
'''
username = forms.CharField(
max_length=32,
error_messages={'required': '用户名不能为空'},
widget=widgets.TextInput(attrs={'class': "form-control"}))
password = forms.CharField(
max_length=32,
error_messages={'required': '密码不能为空'},
widget=widgets.PasswordInput(attrs={'class': "form-control"}))
re_pwd = forms.CharField(
max_length=32,
error_messages={'required': '密码不能为空'},
widget=widgets.PasswordInput(attrs={'class': "form-control"})) email = forms.EmailField(
error_messages={'required': '邮箱不能为空'},
widget=widgets.EmailInput(attrs={'class': "form-control"}))
check_code = forms.CharField(
widget=widgets.TextInput(attrs={'class': "form-control"})) def clean_username(self):
'''
校验用户是否存在
:return:
'''
username = self.cleaned_data.get('username')
user_obj = models.UserInfo.objects.filter(username=username)
if not user_obj:
return username
else:
raise ValidationError('该用户已存在') def clean(self):
'''
校验两次输入的密码是否一致
:return:
'''
password = self.cleaned_data.get('password')
repwd = self.cleaned_data.get('re_pwd')
if password == repwd:
return self.cleaned_data
else:
raise ValidationError("两次密码输入不一致") def clean_email(self):
'''
校验注册邮箱是否已经注册
:return:
'''
email = self.cleaned_data.get('email')
user_obh = models.UserInfo.objects.filter(email=email) if not user_obh:
return email
else:
raise ValidationError("该邮箱已被注册")
form.py
def register(request):
'''
通过ajax实现用户注册
:param request:
:return:
'''
response = {'state': False, 'error_msg':"", 'summary_error': ""} if request.is_ajax():
form_obj = blog_forms.RegisterForm(request.POST)
if form_obj.is_valid():
username = form_obj.cleaned_data.get('username')
password = form_obj.cleaned_data.get('password')
Email = form_obj.cleaned_data.get('email')
valid_code = form_obj.cleaned_data.get('check_code')
avatar_obj = request.FILES.get('avatar')
check_valid = request.session['valid_code']
if valid_code == check_valid:
extra = {}
if avatar_obj:
extra["avatar"] = avatar_obj
blog_obj = models.Blog.objects.create(
title="%s的博客" % username,
site_name="%s的个人站点" % username,
theme="default.css") models.UserInfo.objects.create_user(username=username, password=password, blog=blog_obj, email=Email, **extra)
response['state'] = True
return JsonResponse(response)
else:
response['summary_error'] = '验证码错误'
return JsonResponse(response)
else: response['error_msg'] = form_obj.errors
return JsonResponse(response)
elif request.method == 'GET':
form_obj = blog_forms.RegisterForm()
return render(request, 'register.html', {'form_obj': form_obj})
View.py
WEB框架Django之Form组件的更多相关文章
- 第十一篇:web之Django之Form组件
Django之Form组件 Django之Form组件 本节内容 基本使用 form中字段和插件 自定义验证规则 动态加载数据到form中 1. 基本使用 django中的Form组件有以下几个功 ...
- web之Django之Form组件
Django之Form组件 本节内容 基本使用 form中字段和插件 自定义验证规则 动态加载数据到form中 1. 基本使用 django中的Form组件有以下几个功能: 生成HTML标签 验证用户 ...
- 框架----Django之Form组件
Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 一.小试牛刀 1.创建Form类 from d ...
- Web框架django[Form]组件
新手上路 Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 小试牛刀 1.创建Form类 # 创 ...
- python框架之Django(10)-Form组件
介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来.与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入 ...
- python web框架 Django进阶
django 进阶 基础中,一些操作都是手动创建连接的非主流操作,这样显得太low,当然也是为了熟悉这个框架! 实际中,django自带连接数据库和创建app的机制,同时还有更完善的路由系统机制.既然 ...
- Django之Form组件
Django之Form组件 本节内容 基本使用 form中字段和插件 自定义验证规则 动态加载数据到form中 1. 基本使用 django中的Form组件有以下几个功能: 生成HTML标签 验证用户 ...
- Python之路【第二十一篇】:Django之Form组件
Django之Form组件 Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 小试牛刀 1. ...
- python运维开发(十七)----jQuery续(示例)web框架django
内容目录: jQuery示例 前端插件 web框架 Django框架 jQuery示例 dom事件绑定,dom绑定在form表单提交按钮地方都会绑定一个onclick事件,所有查看网站的人都能看到代码 ...
随机推荐
- KVM虚拟化技术(二)KVM介绍
KVM:Kernel Virtual Machine KVM是基于虚拟化扩展的x86硬件,是Linux完全原生的全虚拟化解决方案.部分半虚拟化支持,主要是通过半虚拟网络驱动程序的形式用于Linux和W ...
- Android EventBus3.x 使用详解
♪(^∇^*) 五一假期在家无事,新项目中用的是RxJava2+EventBus感觉还不错,趁这闲暇总结下EventBus. 一.概要简述 EventBus是一个基于观察者模式的Android事件发布 ...
- IE9及以下版本获取上传文件的大小
IE9及以下版本不能识别files属性:获取图片需要设置浏览器 打开IE_工具_internet选项_安全_自定义级别. 启用ActiveX,开启跨域: var fso=new ActiveXobje ...
- Ajax 学习 第四篇
使用jQuery实现Ajax 跨域
- mysql 查询上个月某一天
本文地址:http://www.cnblogs.com/jying/p/8877065.html 需求:获取上个月15号的日期 网上一搜一大堆粘贴复制的大坑:(如下是查询上个月最后一天,可是我要的不一 ...
- 神经网络中的激活函数具体是什么?为什么ReLu要好过于tanh和sigmoid function?(转)
为什么引入激活函数? 如果不用激励函数(其实相当于激励函数是f(x) = x),在这种情况下你每一层输出都是上层输入的线性函数,很容易验证,无论你神经网络有多少层,输出都是输入的线性组合,与没有隐藏层 ...
- SPSS-回归分析
回归分析(一元线性回归分析.多元线性回归分析.非线性回归分析.曲线估计.时间序列的曲线估计.含虚拟自变量的回归分析以及逻辑回归分析) 回归分析中,一般首先绘制自变量和因变量间的散点图,然后通过数据在散 ...
- Python中struct.pack()和struct.unpack()
https://blog.csdn.net/tjuyanming/article/details/79700601 https://www.cnblogs.com/yezl/p/5861787.htm ...
- yii2-ueditor
扩展下载(yii2.0-ueditor) 框架下载(Yii 2.0.6 高级版) 描述: 最佳适用于yii2.0 高级版(advanced)应用框架,对于基础板(basic)及其他框架要修改对应的命名 ...
- shell脚本中比较两个小数的办法
具体情况#man bc 然而对小数进行比较的相关方法有几个: 1. 自己的解决方法,判断小数点后最多有几位数(N),然后对将要比较的两个数值进行 乘与10的N次方 也就是将小数点去掉来进行比较(小数点 ...