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. Murano为镜像包添加Root用户密码

    1. 安装dib-utils Dib Utils 是 diskimage-builder 工程的一部分,但是他们也用于 diskimage-builder 工程外部. 因为基于云的磁盘空间已经溢出,推 ...

  2. jemeter、windox下安装教程

    JMeter是Apache软件基金会的产品,用于对静态和动态的资源(文件,Servlet,Perl脚本,Java对象,数据库和查询,FTP服务器等等)的性能进行测试,是一款很方便的测试软件. 系统:w ...

  3. Smarty 限制foreach的循环次数

    <!--{foreach from=$news item=news name=foo}--> <!--{if $smarty.foreach.foo.index <7}--&g ...

  4. HDU 4342——History repeat itself——————【数学规律】

    History repeat itself Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. O ...

  5. HDU 5384——Danganronpa——————【AC自动机】

    Danganronpa Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  6. php spl数据结构

    1.双链表SplDoublyLinkedList 结构如图: 类定义: SplDoublyLinkedList implements Iterator , ArrayAccess , Countabl ...

  7. ASP.NET前端调用后台方法

    <script>         function MyConfirm() {             if (confirm('存在重复记录,覆盖点继续,不覆盖追加保存点取消')) { ...

  8. Sql 本周当天本期日期转换

    --查询当天: --查询24小时内的: --info为表名,datetime为数据库中的字段值 --查询当天: --查询24小时内的: select * from table where DateDi ...

  9. springboot从入门到精通(三)

    再开始第三节之前,先补充一下第二节里出现的小问题,就是springboot的application.properties,我在文件中添加了server.port=9090这个参数,但是启动项目后并未生 ...

  10. winform文件拖入

    //view.AllowDrop = true; ---------------------------------------- private void view_DragEnter(DragEv ...