django中的Form有个很重要的功能:验证用户输入

而验证用户输入也可以分为2种:

  (1)前端本身的验证,例如:字段是否可为空,手机号码格式是否正确等;

  (2)前端输入数据和后台数据库数据的验证,例如:注册的用户名是否已存在,邮箱是否注册过等;

本次主要针对第二种情况进行介绍,要实现前后端的数据验证我们可以使用ajax,也可以使用django form的clean_<fieldname>()函数。

下面先看clean_<fieldname>():

一个简单的添加用户的页面:

提交之后对用户进行后台验证,如果存在则会提示。

由上图我们可以的看到效果,具体实现代码:

html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>资源管理系统 - 人员管理</title>
<meta name="description" content="">
<meta name="author" content="templatemo">
<link href="/static/css/font-awesome.min.css" rel="stylesheet">
<link href="/static/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/css/templatemo-style.css" rel="stylesheet"> </head>
<body>
<!-- Left column -->
<div class="templatemo-flex-row">
<div class="templatemo-sidebar">
<div class="profile-photo-container">
<img src="/static/images/logo.png" alt="Profile Photo" class="img-responsive">
<div class="profile-photo-overlay"></div>
</div>
<header class="templatemo-site-header">
<div class="square"></div>
<h1>{{ user }}</h1>
</header> <nav class="templatemo-left-nav">
<ul>
<li><a href="/main/index/"><i class="fa fa-home fa-fw"></i>首页</a></li>
<li><a href="/main/managemachine/"><i class="fa fa-users fa-fw"></i>管理主机</a></li>
<li><a href="/main/manageuser/" class="active"><i class="fa fa-users fa-fw"></i>管理用户</a></li>
<li><a href="/main/managegroup/"><i class="fa fa-users fa-fw"></i>管理属组</a></li>
<li><a href="/main/manageidc/"><i class="fa fa-users fa-fw"></i>管理机房</a></li>
<li><a href="/main/managecity/"><i class="fa fa-users fa-fw"></i>管理城市</a></li>
<li><a href="/main/managerecord/"><i class="fa fa-users fa-fw"></i>巡检记录</a></li>
<li><a href="/main/maps/"><i class="fa fa-map-marker fa-fw"></i>地图</a></li>
<li><a href="/main/logout/"><i class="fa fa-eject fa-fw"></i>退出</a></li>
</ul>
</nav>
</div>
<!-- Main content -->
<div class="templatemo-content col-1 light-gray-bg"> <div class="templatemo-content-container">
<div class="templatemo-content-widget no-padding">
<div class="panel panel-default table-responsive">
<table class="table table-striped table-bordered templatemo-user-table">
<thead>
<tr>
<td>序号</td>
<td>用户名</td>
<td>部门</td>
<td>职位</td>
<td>电话</td>
<td>邮箱</td>
<td>编辑</td>
<td>删除</td>
</tr>
</thead>
<tbody>
{% for item in ret %}
<tr>
<td class="uid">{{ item.0 }}</td>
<td>{{ item.1 }}</td>
<td>{{ item.2 }}</td>
<td>{{ item.3 }}</td>
<td>{{ item.4 }}</td>
<td>{{ item.5 }}</td>
<td class="c1 templatemo-link"><a href="/main/updateuser/?g={{ item.0 }}">Edit</a></td>
<td class="c2 templatemo-link">Delete</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="templatemo-flex-row flex-content-row">
<div class="col-1">
<div class="panel panel-default margin-10">
<div class="panel-heading"><h2 class="text-uppercase">添加用户</h2></div>
<div class="panel-body">
<form action="/main/manageuser/" class="templatemo-login-form" method="POST">
<div class="form-group">
<label for="inputEmail">角色</label><span style="color: red"> *</span>
{{ data.role_choice }}
</div>
<div class="form-group">
<label for="inputEmail">用户名</label><span style="color: red"> *</span>
{{ data.username }}
{% if data.errors.username %}
<span style="color: red">{{ data.errors.username.0 }}</span>
{% endif %}
</div>
<div class="form-group">
<label for="inputEmail">密码</label><span style="color: red"> *</span>
{{ data.password }}
</div>
<div class="form-group">
<label for="inputEmail">确认密码</label><span style="color: red"> *</span>
{{ data.confirm_password }}
{% if data.errors.confirm_password %}
<span style="color: red">{{ data.errors.confirm_password.0 }}</span>
{% endif %}
</div>
<div class="form-group">
<label for="inputEmail">职位</label><span style="color: red"> *</span>
{{ data.job_choice }}
</div>
<div class="form-group">
<label for="inputEmail">邮箱</label>
{{ data.email }}
</div>
<div class="form-group">
<label for="inputEmail">电话</label>
{{ data.phone }}
{% if data.errors.phone %}
<span style="color: red">{{ data.errors.phone.0 }}</span>
{% endif %}
</div>
<div class="form-group">
<input type="submit" class="templatemo-blue-button" value="提交"/>
</div>
</form>
</div>
</div>
</div>
</div>
</div> <!-- Second row ends -->
<div class="pagination-wrap">
<ul class="pagination">
<li><a href="#">1</a></li>
<li><a href="#">2</a></li>
<li class="active"><a href="#">3 <span class="sr-only">(current)</span></a></li>
<li><a href="#">4</a></li>
<li><a href="#">5</a></li>
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true"><i class="fa fa-play"></i></span>
</a>
</li>
</ul>
</div>
<footer class="text-right">
<p>Copyright © 2084 好医生运维部 | Designed by 无名小妖</p>
</footer>
</div>
</div> </body>
</html>

  

from:

class InsertForm(forms.Form):
"""添加用户验证"""
# django给标签加sytle,关键参数widget ,forms.TextInput 表示生成type="text"的input标签,改成Textarea则生成<textarea>标签
rolechoice = (
(1, '管理员'),
(2, '普通用户')
)
role_choice = forms.IntegerField(widget=forms.Select(choices=rolechoice, attrs={'class': 'form-control'}), )
username = forms.CharField(required=True, widget=forms.TextInput(attrs={'class': 'form-control'}))
password = forms.CharField(required=True, widget=forms.PasswordInput(attrs={'class': 'form-control'}),
min_length=6,
max_length=10,
error_messages={'required': '密码不能为空', 'min_length': '至少6位',
'max_length': '至多10位'})
confirm_password = forms.CharField(required=True,
widget=forms.PasswordInput(attrs={'class': 'form-control'}),
min_length=6,
max_length=10,
error_messages={'required': '密码不能为空', 'min_length': '至少6位',
'max_length': '至多10位'})
email = forms.EmailField(widget=forms.TextInput(attrs={'class': 'form-control'}),)
# 自定制验证方法关键就是参数validators,和自己的函数关联起来
phone = forms.CharField(validators=[mobile_validate, ], widget=forms.TextInput(attrs={'class': 'form-control'}),)
# 获取数据库中的职位信息,显示在页面上
userjob = UserJob.objects.all().values_list('job_id', 'job_name')
# list indices must be integers or slices, not str 【此处不能用forms.CharField】
job_choice = forms.IntegerField(widget=forms.Select(choices=userjob, attrs={'class': 'form-control'})) def clean_username(self):
un = self.cleaned_data['username']
user = UserInfo.objects.filter(user_name=un)
if user:
raise ValidationError('用户名已存在!', code='valid')
return self.cleaned_data['username'] def clean_confirm_password(self):
p1 = self.cleaned_data['password']
p2 = self.cleaned_data['confirm_password']
if p1 != p2:
print(p2)
raise forms.ValidationError('两次密码不一致!')
return self.cleaned_data def __init__(self, *args, **kwargs):
"""
实时获取数据相应数据(否则数据库添加的新数据,在页面无法显示)
:param args:
:param kwargs:
"""
super(InsertForm, self).__init__(*args, **kwargs)
self.fields['job_choice'].widget.choices = UserJob.objects.all().values_list('job_id', 'job_name')

  

我们可以重点看 clean_username 函数,由于我们是要验证用户名(对应html 中name=username的input标签,此处我们是通过django from来生成的,可见html的代码),

所以函数名必须叫clean_username,函数内部对后台数据做了提取验证,并返回自定义的错误信息。

下面我们看ajax方式:

一个简单的添加城市的页面:

可以看到对数据的验证,代码就不详细贴了,主要看ajax部分:

<script src="/static/js/jquery-2.1.4.min.js"></script>
<script>
function DoSubmit() {
var input_dic = {};
$('input').each(function () {
var v = $(this).val();
var n = $(this).attr('name');
input_dic[n] = v;
});
$.ajax({
url:'/main/managecity/',
type:'POST',
data:input_dic,
dataType: 'json',
success: function (msg) {
if(msg.status){
location.href = '/main/managecity/'
}else{
$('#id_city_name').each(function () {
var tag = document.createElement('span');
tag.style = 'color: red';
tag.innerText = msg.message;
$(this).after(tag);
})
}
}
})
}

  

获取用户输入的数据,通过ajax传到views中对应的函数,通过函数进行后台数据验证。

views:

def managecity(req):
username = req.session.get('username')
ret = City.objects.all()
msg = {'status': False, 'message': None}
# 插入数据
if req.POST:
fm = CityForm(req.POST)
if fm.is_valid():
# 获取表单信息
city_name = fm.cleaned_data['city_name']
city = City.objects.filter(city_name=city_name).count()
if city:
msg['message'] = '数据已存在!'
else:
msg['status'] = True
City.objects.create(city_name=city_name)
return HttpResponse(json.dumps(msg)) # 将数据发送给ajax回调函数
else:
msg['message'] = '请填写此字段!'
return HttpResponse(json.dumps(msg)) # 将数据发送给ajax回调函数
else:
fm = CityForm() return render(req, 'manage-citys.html', {'user': username, 'data': ret, 'city': fm})

  

验证完之后,在通过ajax回调函数将提示信息显示在页面上显示。

总结:

这两种方式都实现了对表单数据的后台验证,

django form 的好处是只需要在定义一个函数即可,并且前端是看不到如何实现的,缺点是只能在django框架用;

而ajax在前端是可以通过查看页面代码看到的,好处是不管什么框架都可以用,而且ajax是“偷偷”发数据,页面不会刷新,但是django form会刷新页面;

有兴趣 可以看一下clean源码:

django表单的字段验证(clean_<fieldname>())和ajax的字段验证的更多相关文章

  1. django 表单验证和字段验证

    表单验证和字段验证 表单验证发生在数据验证之后.如果你需要自定义这个过程,有几个不同的地方可以修改,每个地方的目的不一样.表单处理过程中要运行三种类别的验证方法.它们通常在你调用表单的is_valid ...

  2. Django表单介绍

    HTML 表单 在HTML中,表单是<form>...</form> 之间元素的集合,它们允许访问者输入文本.选择选项.操作对象和控制等等,然后将信息发送回服务器. 某些表单的 ...

  3. django表单使用

    一.表单常用字段类型及参数 表单可以自动生成html代码,每一个字段默认有一个html显示样式,大多数默认为输入框. 字段相当于正则表达式的集合,能够对表单传入的数据进行校验,并且某一部分校验失败时会 ...

  4. python 全栈开发,Day111(客户管理之 编辑权限(二),Django表单集合Formset,ORM之limit_choices_to,构造家族结构)

    昨日内容回顾 1. 权限系统的流程? 2. 权限的表有几个? 3. 技术点 中间件 session orm - 去重 - 去空 inclusion_tag filter 有序字典 settings配置 ...

  5. python3之Django表单(一)

    1.HTML中的表单 在HTML种,表单是在<form>...</form>种的元素,它允许用户输入文本,选择选项,操作对象等,然后发送这些数据到服务器 表单元素允许用户在表单 ...

  6. django表单的api

    django表单的api,参考文档:https://yiyibooks.cn/xx/Django_1.11.6/ref/forms/api.html 绑定与未绑定形式: Form要么是绑定的,要么是未 ...

  7. Django表单API详解

    声明:以下的Form.表单等术语都指的的广义的Django表单. Form要么是绑定了数据的,要么是未绑定数据的. 如果是绑定的,那么它能够验证数据,并渲染表单及其数据,然后生成HTML表单.如果未绑 ...

  8. Django 表单处理流程

    Django 的表单处理:视图获取请求,执行所需的任何操作,包括从模型中读取数据,然后生成并返回HTML页面(从模板中),我们传递一个包含要显示的数据的上下文.使事情变得更复杂的是,服务器还需要能够处 ...

  9. 第四章:Django表单 - 2:Django表单API详解

    声明:以下的Form.表单等术语都指的的广义的Django表单. Form要么是绑定了数据的,要么是未绑定数据的. 如果是绑定的,那么它能够验证数据,并渲染表单及其数据,然后生成HTML表单.如果未绑 ...

  10. 第四章:Django表单 - 1:使用表单

    假设你想从表单接收用户名数据,一般情况下,你需要在HTML中手动编写一个如下的表单元素: <form action="/your-name/" method="po ...

随机推荐

  1. Python输出中文到文件时的字符编码问题

    今天在使用Python的GUI平台wxPython时,写了一个只有打开.编辑.保存功能的简易笔记本,代码如下: #coding:utf-8 import wx def load(event): f = ...

  2. 敏捷开发之scrum模型

    什么是敏捷开发? 敏捷开发(Agile Development)是一种以人为核心.迭代.循序渐进的开发方法. 怎么理解呢?首先,我们要理解它不是一门技术,它是一种开发方法,也就是一种软件开发的流程,它 ...

  3. [Git]Git指南一 查看创建删除标签

    1. 查看标签 列出现有标签,使用如下命令: xiaosi@yoona:~/code/learningnotes$ git tag r-000000-000000-cm.cm v1.0.0 v1.0. ...

  4. eclipse 智能提示js和jquery等前端插件

    使用Eclipse写Jquery和Javascript代码的时候,是没有智能提示的.我们可以使用一个插件来解决这个问题. 安装完成后,Eclipse会自动重启.重启之后,我们在项目上右键,   根据自 ...

  5. Go语言的序列化与反序列化(gob)

    encoding/gob包实现了高效的序列化,特别是数据结构较复杂的,结构体.数组和切片都被支持. 实现代码如下://定义一个结构体type Student struct { Name string ...

  6. 多进程(了解):守护进程,互斥锁,信号量,进程Queue与线程queue(生产者与消费者模型)

    一.守护进程 主进程创建守护进程,守护进程的主要的特征为:①守护进程会在主进程代码执行结束时立即终止:②守护进程内无法继续再开子进程,否则会抛出异常. 实例: from multiprocessing ...

  7. SQLServer清空数据库中所有表的数据

    今早同事跟进客户反馈的问题时,提了个要求,要求清空数据库中所有表的数据. 记得之前用游标遍历所有的表名 + exec 动态语句 truncate table 表名 实现过这个功能. 网上搜了下,有更简 ...

  8. kali视频(16-20)学习

    第五周 kali视频(16-20)学习 16.漏洞分析之数据库评估(一) 17.漏洞分析之数据库评估(二) 18.漏洞分析之WEB应用代理 19.漏洞分析之burpsuite 20.漏洞分析之fuzz ...

  9. C#合成解析XML与JSON

      http://www.xuanyusong.com/archives/1901  XML与JSON在开发中非常重要, 其实核心就是处理字符串.一个是XML的字符串一个是JSON的字符串,尤其是在处 ...

  10. linux下修改ip地址

    1.more  /etc/sysconfig/network-scripts/ifcfg-eth0 2.ifconfig eth0 192.168.1.211 netmask 255.255.255. ...