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组件的更多相关文章

  1. 第十一篇:web之Django之Form组件

    Django之Form组件   Django之Form组件 本节内容 基本使用 form中字段和插件 自定义验证规则 动态加载数据到form中 1. 基本使用 django中的Form组件有以下几个功 ...

  2. web之Django之Form组件

    Django之Form组件 本节内容 基本使用 form中字段和插件 自定义验证规则 动态加载数据到form中 1. 基本使用 django中的Form组件有以下几个功能: 生成HTML标签 验证用户 ...

  3. 框架----Django之Form组件

    Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 一.小试牛刀 1.创建Form类 from d ...

  4. Web框架django[Form]组件

    新手上路 Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 小试牛刀 1.创建Form类 # 创 ...

  5. python框架之Django(10)-Form组件

    介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来.与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入 ...

  6. python web框架 Django进阶

    django 进阶 基础中,一些操作都是手动创建连接的非主流操作,这样显得太low,当然也是为了熟悉这个框架! 实际中,django自带连接数据库和创建app的机制,同时还有更完善的路由系统机制.既然 ...

  7. Django之Form组件

    Django之Form组件 本节内容 基本使用 form中字段和插件 自定义验证规则 动态加载数据到form中 1. 基本使用 django中的Form组件有以下几个功能: 生成HTML标签 验证用户 ...

  8. Python之路【第二十一篇】:Django之Form组件

    Django之Form组件   Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 小试牛刀 1. ...

  9. python运维开发(十七)----jQuery续(示例)web框架django

    内容目录: jQuery示例 前端插件 web框架 Django框架 jQuery示例 dom事件绑定,dom绑定在form表单提交按钮地方都会绑定一个onclick事件,所有查看网站的人都能看到代码 ...

随机推荐

  1. 360Top奢侈品演示站 - 纯手工纪念品

    一个纯手写的过程化编程商城项目,留作纪念. 360Top奢侈品演示站 http://360top.farwish.com

  2. postmessage/cors跨域postMessage、xhr2和xmldomain

    一.h5 postMessage node http-server配置服务器 有关配置:请参考我的http://www.cnblogs.com/leee/p/5502727.html 我把文件夹a配置 ...

  3. week5 04 npm run build

    上期 我们完成了nodeserver的创建 用的是express genrealtor那个工具 我们在server端执行 起来了 然后我们改一下 删一下 我们觉着暂时没用的东西 首先去app.js程序 ...

  4. 16.1 用auth0服务 实现用登录和管理 使用auth版本的2个大坑。

    这是三周内容,实现用户登录和管理 回到master分支 切换到 han分支 更新一下 然后工作 开始工作写代码了 安装2个angular端的auth0的lib,也可不安装,后边有不安装的做法 不安装的 ...

  5. Jetty-attack-test

    import httplib, urllib, ssl, string, sys, getopt from urlparse import urlparse ''' Author: Gotham Di ...

  6. 使用__slots__限制实例的属性

    1.给实例化的对象添加新的属性 看下面一段代码,然后给实例化的对象s添加或者修改属性 class Student(object): name='china' s = Student() s1=Stud ...

  7. C++ 学习 之Struct

    转自https://blog.csdn.net/bestconvenient/article/details/30734139 最开始,就让我们来讨论一下一个最最基本,也最最容易被人忽视掉的问题——C ...

  8. 初识Swift中的值和引用,循坏引用、代理的注意点

    1.0 在Swift中分有值类型和引用类型 Int .String . 结构体和枚举都属于值类型, 将值类型传递给方法是,将在内存中创建其副本,并传递这个副本:这样我们就可以随心所欲修改它,而不用担心 ...

  9. 吴裕雄 python深度学习与实践(1)

    #coding = utf8 import threading,time count = 0 class MyThread(threading.Thread): def __init__(self,t ...

  10. NYOJ20-吝啬的国度-图-dfs

    20-吝啬的国度 内存限制:64MB时间限制:1000ms特判: No 难度:3 题目描述: 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市, ...