1.用处

  1、用户请求数据验证

  2、自动生成错误信息

  3、打包用户提交的正确信息

  4、如果其中有一个错误了,其他的正确,则保留上次输入的内容

  5、自动创建input标签并可以设置样式

  6.基于forms实现增删改查

2.使用方法

对于注册信息进行校验

在应用下创建一个forms.py文件(起什么名无所谓,后面在视图函数中直接导入进来使用)

from django import forms
from django.forms import widgets
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError class UserInfo(forms.Form):
username = forms.CharField(
required=True, # 标明是必填字段,不能为空
min_length=4, max_length=12,
label="姓名", # 给定字段名称,直接把username换成了姓名
error_messages={"required": "用户名不能为空!!"},
widget=widgets.TextInput(attrs={"placeholder": "用户名", "class": "form-control"}) # 自动生成input框
) password = forms.CharField(
widget=widgets.PasswordInput(attrs={"placeholder":"密码","class":"form-control"}),
label="密码",
) sec_pwd = forms.CharField(
required=True,
label="二次密码",
widget=widgets.PasswordInput(attrs={"placeholder":"二次密码","class":"form-control"})
) age = forms.IntegerField(
label="年龄",
widget = widgets.NumberInput(attrs={"placeholder":"年龄","class":"form-control"}),
error_messages={"required": "输入不对!!"},
) email = forms.EmailField(
widget=widgets.EmailInput(attrs={"placeholder":"邮箱","class":"form-control"}),
label="邮箱",
error_messages={"invalid": "格式错误"}
) # 定制化二次错误信息 # 局部钩子
# 注意这里必须是以clean_ 开头,可以查看源码,下面得到的val都是字符串类型
def clean_username(self):
val = self.cleaned_data.get("username")
if not val.isdigit():
return val
else:
raise ValidationError("用户名非纯数字") def clean_password(self):
val = self.cleaned_data.get("password")
if len(val) > 3:
return val
else:
raise ValidationError("密码太短") def clean_age(self):
val = self.cleaned_data.get("age")
if int(val) > 18:
return val
else:
raise ValidationError("岁数太小") # 全局钩子
# 对于两次输入的密码进行校验是否一致
def clean(self):
password = self.cleaned_data.get("password")
sec_pwd = self.cleaned_data.get("sec_pwd")
if password == sec_pwd:
return self.cleaned_data
else:
raise ValidationError("两次密码不一致")

  这个类到底干了什么事呢??你在解释器中打印就会发现,第一件事就是将自己显示成HTML。form对象做的第二件事就是来校验信息

  调用任何绑定form的is_valid()方法,就可以知道它的数据是否合法

  Django的form系统自动寻找匹配的函数方法,该方法名称以 clean_ 开头,并以字段名称结束。 如果有这样的方法,它将在校验时被调用。这属于一次额外校验

  如果存在异常,我们抛出一个 forms.ValidationError 型异常,这个异常的描述会被作为错误列表中的一项显示给用户

views.py

from django.shortcuts import render,HttpResponse
# Create your views here.
from app01.form import UserInfo def index(request):
# 定制化提示信息,
if request.method=="POST":
form = UserInfo(request.POST)
# 如果全部输入信息有效
if form.is_valid():
return HttpResponse("添加成功")
else:
# 打印输入的信息
print("---",form.cleaned_data) # 得到一个字典
print("???",form.errors) # ErrorDict : {"校验错误的字段":["错误信息",]}
print("!!!",form.errors.get("email")) # ErrorList ["错误信息",] g_error = form.errors.get("__all__")
print("+++",g_error) # <ul class="errorlist nonfield"><li>两次密码不一致</li></ul>
if g_error:
g_error = g_error[0] # 直接获取你自己的错误提示,即两次密码不一致 return render(request, "index.html", locals()) else:
form = UserInfo()
return render(request, "index.html", locals())

这里form.py和创建的视图函数衔接关键点就在于 form = UserInfo(request.POST)

模板渲染:

方式一:

以p标签的样式展现出来,当然也能以能table标签展示

index.html

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.error {
color: red;
}
</style>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css">
</head>
<body>
<h3>注册用户</h3>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
{# 这个novalidate很重要啊,没有这个后面自己定制的错误提示无法渲染出来 #}
{# 自己编写表单验证插件的时候,使用它可以避免和默认的表单验证冲突 #}
<form action="" method="post" novalidate>
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>

</div>
</div>
</div> </body>
</html>

# 要注意这里form表单中添加的属性novalidate,它能够避免和默认的表单验证发生冲突

方式二:

书写相对麻烦

<form action="" method="post" novalidate>
{% csrf_token %}
<div>
<p>姓名</p>
{{ form.username }}
</div>
<div>
<p>密码</p>
{{ form.password }}
</div>
<div>
<p>二次密码</p>
{{ form.sec_pwd }}
</div>
<div>
<p>年龄</p>
{{ form.age }}
</div>
<div>
<p>年龄</p>
{{ form.email }}
</div>
<input type="submit"> </form>

方式三(常用):

<form action="" method="post" novalidate>
{% csrf_token %}
{% for foo in form %}
<div class="form-group">
{# 渲染出lable标签,标签后面是输入框 #}
<lable>{{ foo.label }}</lable>{{ foo }}
{# 专门定制报错信息 #}
<span class="error pull-right">{{ foo.errors.0 }}</span>
{# 对于二次输入报错信息进行设置 #}
{% if foo.label == "二次密码" %}
<span class="error pull-right">{{ g_error|default_if_none:"" }}</span>
{% endif %}
</div>
{% endfor %}
<input type="submit" class="btn btn-default btn-sm">
</form>

3.基于forms组件的ModelForm实现的增删改查

models.py

from django.db import models

class Depart(models.Model):
caption = models.CharField(max_length=32) def __str__(self):
return self.caption
class Role(models.Model):
title = models.CharField(max_length=32) def __str__(self):
return self.title class User(models.Model): name = models.CharField(verbose_name='姓名',max_length=32)
depart = models.ForeignKey(verbose_name='部门',to='Depart',on_delete=models.CASCADE) gender_choices = (
(1,'男'),
(2,'女'),
)
gender = models.IntegerField(verbose_name='性别',choices=gender_choices,default=1) roles = models.ManyToManyField(verbose_name='角色',to='Role')

urls.py

from django.contrib import admin
from django.urls import path,re_path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path('user/list/$', views.user_list),
re_path('user/add/$', views.user_add),
re_path('user/edit/(?P<uid>\d+)/$', views.user_edit),
re_path('user/del/(?P<uid>\d+)/$', views.user_del),
]

views.py

from django.shortcuts import render,redirect
from app01 import models def user_list(request):
user_queryset = models.User.objects.all()
return render(request,'user_list.html',{'user_queryset':user_queryset}) from django import forms
class UserForm(forms.ModelForm):
class Meta:
model = models.User
fields = '__all__'
# fields = ['name','depart']
widgets = {
'name':forms.TextInput(attrs={'class':'form-control'}),
'depart':forms.Select(attrs={'class':'form-control'}),
'gender':forms.Select(attrs={'class':'form-control'}),
'roles':forms.SelectMultiple(attrs={'class':'form-control'}),
}
error_messages = {
'name':{
'required':'用户名不能为空'
}
} def user_add(request):
if request.method == "GET":
form = UserForm()
else:
form = UserForm(request.POST)
if form.is_valid():
print('通过验证')
form.save()
return redirect('/user/list/')
return render(request,'user_add.html',{'form':form}) def user_edit(request,uid):
obj = models.User.objects.filter(id=uid).first()
if request.method =='GET':
form = UserForm(instance=obj)
return render(request,'user_edit.html',{'form':form})
else:
form = UserForm(data=request.POST,instance=obj)
if form.is_valid():
form.save()
return redirect('/user/list/')
else:
return render(request, 'user_edit.html', {'form': form}) def user_del(request,uid):
models.User.objects.filter(id=uid).delete()
return redirect('/user/list/')

user_list.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<a href="/user/add/" class="btn btn-primary">添加</a>
<table class="table table-bordered">
<thead>
<tr>
<th>名称</th>
<th>性别</th>
<th>部门</th>
<th>角色</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for row in user_queryset %}
<tr>
<td>{{ row.name }}</td>
<td>{{ row.get_gender_display }}</td>
<td>{{ row.depart.caption }}</td>
<td>
{% for node in row.roles.all %}
<span>{{ node.title }}</span>
{% endfor %}
</td>
<td>
<a href="/user/edit/{{ row.id }}/">编辑</a>
<a href="/user/del/{{ row.id }}/">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>

user_edit.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<h1>编辑用户</h1>
<form method="post" novalidate>
{% csrf_token %}
{% for field in form %}
<div>{{ field.label }}{{ field }} {{ field.errors.0 }}</div>
{% endfor %}
<input type="submit" value="提交">
</form>
</body>
</html>

user_add.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<h1>添加用户</h1>
<form method="post" class="form-horizontal" novalidate>
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label class="col-sm-2 control-label">{{ field.label }} </label>
<div class="col-sm-10">
{{ field }} {{ field.errors.0 }}
</div>
</div>
{% endfor %}
<input type="submit" value="提交">
</form>
</div>
</body>
</html>

效果:

这里其他效果:

django中的forms组件(权限信息校验,增删改查)的更多相关文章

  1. Django中ORM表的创建以及基本增删改查

    Django作为重量级的Python web框架,在做项目时肯定少不了与数据库打交道,编程人员对数据库的语法简单的还行,但过多的数据库语句不是编程人员的重点对象.因此用ORM来操作数据库相当快捷.今天 ...

  2. django中的forms组件

    form介绍 用户需要向后端提交一些数据时,我们常常把这些数据放在一个form表单里,采用form标签,里面包含一些input等标签把用户的数据提交给后端. 在给后端提交数据的时候,我们常常也需要对于 ...

  3. Django框架之第二篇--app注册、静态文件配置、form表单提交、pycharm连接数据库、django使用mysql数据库、表字段的增删改查、表数据的增删改查

    本节知识点大致为:静态文件配置.form表单提交数据后端如何获取.request方法.pycharm连接数据库,django使用mysql数据库.表字段的增删改查.表数据的增删改查 一.创建app,创 ...

  4. Node教程——Node+MongoDB案例实现用户信息的增删改查

    想要获取源代码的同学可以留言,我不做git上传了,案例太简单 没必要 综合演练 用户信息的增删改查 需求:你需要实现这样的结果 点击添加可以添加用户,点击删除可以删除点击修改可以修改 代码分析: 1. ...

  5. Django 之 文件配置、pycharm及django连接数据库、创表及表的增删改查02

    目录 创建项目后的文件夹配置 静态文件配置 接口前缀动态绑定 form表单回顾 根据请求方式的不同,返回前端不同的信息 pycharm 连接MYSQL数据库 Django 连接MYSQL数据库的配置 ...

  6. mysql 的安装,密码及修改 ,权限,基础语句(增删改查)

    参考网址:https://www.cnblogs.com/majj/p/9160383.html    (安装等) https://www.cnblogs.com/majj/p/9160421.htm ...

  7. 在python中连接mysql数据库,并进行增删改查

    数据库在开发过程中是最常见的,基本上在服务端的编程过程中都会使用到,mysql是较常见的一种数据库,这里介绍python如果连接到数据库中,并对数据库进行增删改查. 安装mysql的python扩展 ...

  8. 关于android中数据库的创建以及基础的增删改查的相应操作

    这里主要是掌握一些基本的相应的知识,具体的是阿金是等到明天在进行. 相应的知识点如下: 对于数据库中的一些常识.SQLite 没有服务器进程,它通过文件保存数据,该文件是跨平台的,可以放在其他平台中使 ...

  9. 小白学Python-S3-day04-用户信息的增删改查、变更权限

    一.用户信息 文件中每一行就是用户的详细信息,每一行是按照冒号为分隔符分成七段 第一段用户名,第二段密码占位符,第三段UID,第四段GID,第五段是描述信息,第六段是家目录.第七段是 是否 可以登录操 ...

随机推荐

  1. ElasticSearch 服务搭建

    一.搭建环境 操作系统:Win7 ElasticSearch:1.73 Java JDK:1.7 二.搭建操作 1.安装Java JDK,然后配置系统环境变量,新建CLASS_PATH(jre所在目录 ...

  2. JavaScript操作符(=?,)优先级

    JavaScript操作符优先级: 关于最后3个运算符的优先级比较,下面通过一个实例来具体说明: var a,b,c; a = 3,4,5; b = a--,--a,a; c = a ? b++ : ...

  3. stm32中断优先级快速入门

    1.基本概念 STM32(Cortex-M3架构)中有两个优先级的概念--抢占式优先级和响应优先级.有人把响应优先级称作'亚优先级'或'副优先级',每个中断源都需要被指定这两种优先级. 具有高抢占式优 ...

  4. c#-day04学习笔记

    面向对象 类与对象: C#的类和对象是用于在程序中模拟现实生活中的事务的 C#中的类是一种数据类型,用来定义对象的类型的 C#的对象是类的实例,是基于[给定数据类型]的具体的一个实例 小结: 类是对象 ...

  5. Git提交代码到主分区

    git 提交代码,本地新建一个my分支,不从本地master分支直接上传,而是先从本地my分支上提交至本地master分支,然后本地master提交至远程master分支 上.前提是远程只有一个mas ...

  6. mysql 将null转代为0(转)

    1.如果为空返回0 select ifnull(null,0) 2.如果为空返回0,否则返回1 select if(isnull(col),0,1) as col. MYSQL 中的IFNULL函数 ...

  7. kafka的分区分配策略

    用过 Kafka 的同学应该都知道,每个 Topic 一般会有很多个 partitions.为了使得我们能够及时消费消息,我们也可能会启动多个 Consumer 去消费,而每个 Consumer 又会 ...

  8. jQuery遍历节点

    html代码 <div> <p>武汉长乐教育</p> <span>在哪才能真正学习会PHP技术?</span> <a href=&qu ...

  9. 超链接导致window.location.href失效的解决办法

    通常我们采用 window.location.href 执行页面间的跳转,比如下面的语句 window.location.href = 'https://www.baidu.com/'; 一般执行上面 ...

  10. es6-Set和Map数据结构

    Set 基本用法 ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个构造函数,用来生成 Set 数据结构. const s = new Set ...