python自动化开发-[第二十天]-form表单,CBV和FBV,序列化
1、CBV和FBV的用法
2、序列化用法
3、form表单
一、CBV和FBV
1、cbv是 class based view(基于类),fbv是function based view(基于函数)
2、cbv基于dispatch进行反射,get获取,post提交
3、应用场景:登录认证(继承dispatch,在dispatch里做session验证)
CBV第一种方式继承
1、单继承
扫盲:(继承的时候,一定要清楚self是哪个类实例化出来的对象,下例,self为B实例化的对象,任何属性优先从自己里面找,找不到在去父类里找)
class A(object):
def aaa(self):
print('from A')
def bbb(self):
self.aaa() class B(A):
def aaa(self):
print('from B') c = B()
c.aaa()
from django.views import View
class BaseView(View):
def dispatch(self, request, *args, **kwargs): # 继承父类的dispatch,因为父类里有返回值,所以也要有return
if request.session.get('username'):
response = super(BaseView, self).dispatch(request, *args, **kwargs)
return response
else:
return redirect('/login.html') class IndexView(BaseView): def get(self, request, *args, **kwargs):
return HttpResponse(request.session['username'])
2、多继承(继承顺序从左到右)
class BaseView(object):
def dispatch(self, request, *args, **kwargs):
if request.session.get('username'):
response = super(BaseView,self).dispatch(request, *args, **kwargs)
return response
else:
return redirect('/login.html') class IndexView(BaseView,View):#先去找BaseView,BaseView中未定义在去找View def get(self,request,*args,**kwargs):
return HttpResponse(request.session['username'])
CBV第二种方式装饰器
from django.utils.decorators import method_decorator def auth(func): #定义装饰器
def inner(request,*args,**kwargs):
if request.session.get('username'):
obj = func(request,*args,**kwargs)
return obj
else:
return redirect('/login.html')
return inner @method_decorator(auth,name='get') #放在类顶部就需要method_decorator这个装饰器
class IndexView(View): @method_decorator(auth) #放在dispatch上就相当于全局都需要经过认证
def dispatch(self, request, *args, **kwargs):
if request.session.get('username'):
response = super(IndexView,self).dispatch(request, *args, **kwargs)
return response
else:
return redirect('/login.html') @method_decorator(auth)
def get(self,request,*args,**kwargs):
return HttpResponse(request.session['username']) @method_decorator(csrf_exempt) # 无效 csrf 放到post函数上的装饰器,是无效的,需要放到dispath上或者类上
def post(self,request,*args,**kwargs):
return HttpResponse(request.session['username'])
特殊csrf
特殊:CSRF
class IndexView(View): @method_decorator(csrf_exempt) #不能放属性上,只能放在全局
def dispatch(self, request, *args, **kwargs):
return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request,*args,**kwargs):
return HttpResponse(request.session['username']) def post(self,request,*args,**kwargs):
return HttpResponse(request.session['username'])
二、序列化
方式一 serialize,可以序列化对象
user_list = models.UserInfo.objects.all()
data = serializers.serialize("json", user_list)
[
{"model": "app01.userinfo", "pk": 1, "fields": {"username": "\u5174\u666e", "password": "123123"}},
{"model": "app01.userinfo", "pk": 2, "fields": {"username": "\u94f6\u79cb\u826f", "password": "666"}}
]
方式二 json dumps(只能序列化python支持的数据类型)
user_list = models.UserInfo.objects.values('id','username')
user_list = list(user_list)
data = json.dumps(user_list)
[
{"username": "\u5174\u666e", "id": 1},
{"username": "\u94f6\u79cb\u826f", "id": 2}
]
json dumps不能序列化时间,通过自定义来支持序列化时间
import json
from datetime import date
from datetime import datetime class JsonCustomEncoder(json.JSONEncoder):
def default(self, field):
if isinstance(field, datetime):
return field.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(field, date):
return field.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self, field) user_list = [
{'id':1,'name':'alex','ctime': datetime.now()},
{'id':2,'name':'eric','ctime': datetime.now()}
] data = json.dumps(user_list,cls=JsonCustomEncoder)
print(data) '''
[{"ctime": "2017-09-15 06:47:53", "id": 1, "name": "alex"}, {"ctime": "2017-09-15 06:47:53", "id": 2, "name": "eric"}] '''
三、Form表单验证
1、form表单的功能
表单验证和生成表单
示例:用户管理
a. 添加用户页面
- 显示HTML标签
- 提交:数据验证
- 成功之后保存
- 错误显示错误信息
创建Form类(本质就是正则表达式的集合)
from django.forms import Form
from django.forms import fields
from django.forms import widgets class UserForm(Form):
username = fields.CharField(
required=True, #默认就为true,可以不填
error_messages={'required':'用户名不能为空'}, #自定义错误信息
widget=widgets.TextInput(attrs={'class':'form-control'}) #额外自定义样式
)
password = fields.CharField(
required=True,
error_messages={'required': '邮箱不能为空','invalid':'邮箱格式错误'}, #邮箱的错误提示需要写在invalid里
widget = widgets.TextInput(attrs={'class': 'form-control'})
)
# fields.EmailField()
# fields.GenericIPAddressField(protocol='ipv4') ut_id = fields.ChoiceField( #单选和多选会有个下拉框内容填充的问题,默认类的属性只加载一次,需要通过构造方法,使得每次调用都更新一次
choices=[],
widget=widgets.Select(attrs={'class':'form-control'})
) role_id = fields.MultipleChoiceField(
choices=[],
widget=widgets.SelectMultiple(attrs={'class':'form-control'})
) def __init__(self,*args,**kwargs):
super(UserForm,self).__init__(*args,**kwargs)
# self.fields已经有所有拷贝的字段
self.fields['ut_id'].choices = models.UserType.objects.values_list('id','title')
self.fields['role_id'].choices = models.Role.objects.values_list('id','caption')
例子添加用户:
view里
from django.forms import Form,fields,widgets
class UserForm(Form):
'''用户表单'''
username = fields.CharField(required=True,error_messages={'required':'用户名不能为空'}) password = fields.CharField(required=True,error_messages={'required':'密码不能为空'}) # ip = fields.GenericIPAddressField(required=True,error_messages={'required':'IP不能为空','invalid':'IP格式错误'}) ut_id = fields.ChoiceField(choices=[])
def __init__(self,*args,**kwargs):
super(UserForm,self).__init__(*args,**kwargs)
self.fields['ut_id'].choices = models.UserType.objects.values_list('id','title')
class AddUserView(AuthView,View):
'''添加视图''' def get(self,request,*args,**kwargs):
form = UserForm()
return render(request,'add_user.html',{'form':form}) def post(self,request,*args,**kwargs):
form = UserForm(request.POST)
if form.is_valid():
print(form.cleaned_data)
models.UserInfo.objects.create(**form.cleaned_data)
return redirect('/users.html')
else:
print(form.errors)
return render(request,'add_user.html',{"form":form})
tempelate:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>添加用户</h1>
<form method="POST" novalidate>
{% csrf_token %}
<p>
用户名: {{ form.username }} {{ form.errors.username.0 }}
</p>
<p>
密码: {{ form.password }} {{ form.errors.password.0 }}
</p>
{# <p>#}
{# ip: {{ form.ip }} {{ form.errors.ip.0 }}#}
{# </p>#}
<p>
用户类型: {{ form.ut_id }} {{ form.errors.ut_id.0 }}
</p>
<input type="submit" value="提交">
</form>
</body>
</html>
知识点:form(request.POST),将request内的数据传递给from表单,form表单会进行正则验证,通过obj.is_valid(), 如果正常, 返回值就是obj.cleaned_data,如果出现异常,异常信息会以字典形式存放在obj.errors 。一个输入框多条错误信息 一般只取第一条错误信息,处理完这一条在去处理其他
带默认值的添加标签:
class EditUserView(AuthView,View):
def get(self,request,pk):
obj = models.UserInfo.objects.filter(id=pk).first()
role_id_list = obj.rl.values_list('id')
v = list(zip(*role_id_list))[0] if role_id_list else []
form = UserForm(initial={'username': obj.username, 'password': obj.password, 'ut_id': obj.ut_id,'role_id':v})
return render(request,'edit_user.html',{'form':form}) def post(self,request,pk):
form = UserForm(data=request.POST)
if form.is_valid():
# # {'username': 'xxxxx', 'password': 'xxxxx', 'ut_id': '1',role_id:}
role_id = form.cleaned_data.pop('role_id')
# 用户表更新
query = models.UserInfo.objects.filter(id=pk)
query.update(**form.cleaned_data)
obj = query.first()
obj.rl.set(role_id) return redirect('/users.html')
else:
print(form.errors)
return render(request, 'edit_user.html', {'form': form})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>编辑用户</h1>
<form method="POST" novalidate>
{% csrf_token %}
<p>
用户名: {{ form.username }} {{ form.errors.username.0 }}
</p>
<p>
密码: {{ form.password }} {{ form.errors.password.0 }}
</p>
{# <p>#}
{# ip: {{ form.ip }} {{ form.errors.ip.0 }}#}
{# </p>#}
<p>
用户类型: {{ form.ut_id }} {{ form.errors.ut_id.0 }}
</p>
<input type="submit" value="提交">
</form>
</body>
</html>
通过ajax+form表单验证,实现注册功能
view:
class RegisterForm(Form):
user = fields.CharField(required=True,min_length=6,max_length=18)
email = fields.EmailField(required=True,min_length=6,max_length=18)
password = fields.CharField(min_length=12)
import json def register(request):
if request.method == 'GET':
form = RegisterForm()
return render(request,'register.html',{'form':form})
else:
response = {'status': True,'data': None,'msg':None}
form = RegisterForm(request.POST)
if form.is_valid():
print(form.cleaned_data)
# 数据库中添加一条数据
# return redirect('/login.html') # ajax跳转,错错错
else:
response['status'] = False
response['msg'] = form.errors
return HttpResponse(json.dumps(response))
tempelate
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id="f1">
{% csrf_token %}
<p>用户名:{{ form.user }}</p>
<p>密码:{{ form.password }}</p>
<p>邮箱:{{ form.email }}</p>
<input type="button" value="提交" onclick="submitForm();" />
</form>
<script src="/static/jquery-3.2.1.js"></script>
<script>
function submitForm() {
$('#f1 .error').remove(); $.ajax({
url: '/register.html',
type: 'POST',
data: $('#f1').serialize(),
dataType: 'JSON',
success:function (arg) {
if(arg.status){
location.href = "/login.html";
}else{
/*
arg.msg = {
email: ['xxxxx',]
password: ['xxxxx',]
user: ['xxxxx',]
}
*/
$.each(arg.msg,function (k,v) {
var tag = document.createElement('span');
tag.innerHTML = v[0];
tag.className = "error";
// <span class='error'>v[0]</span>
$('#f1 input[name="'+k+'"]').after(tag);
})
}
}
})
}
</script> </body>
</html>
python自动化开发-[第二十天]-form表单,CBV和FBV,序列化的更多相关文章
- 巨蟒python全栈开发django11:ajax&&form表单上传文件contentType
回顾: 什么是异步? 可以开出一个线程,我发出请求,不用等待返回,可以做其他事情. 什么是同步? 同步就是,我发送出了一个请求,需要等待返回给我信息,我才可以操作其他事情. 局部刷新是什么? 通过jq ...
- python自动化开发-[第二十一天]-form验证,中间件,缓存,信号,admin后台
今日概要: 1.form表单进阶 2.中间件 3.缓存 4.信号 5.admin后台 上节课回顾 FBV,CBV 序列化 - Django内置 - json.dumps(xxx,cls=) Form验 ...
- JavaBean+jsp开发模式 --结合form表单 实例
1.创建form表单 <%@ page language="java" contentType="text/html; charset=UTF-8" pa ...
- 微信小程序开发4之form表单与弹出层
第一 表单的提交和重置 第二 radio组件 第三 checkbox组件 第四 loading组件 第五 toast组件 第六 modal组件
- [js开源组件开发]query组件,获取url参数和form表单json格式
query组件,获取url参数和form表单json格式 距离上次的组件[js开源组件开发]ajax分页组件一转眼过去了近二十天,或许我一周一组件的承诺有了质疑声,但其实我一直在做,只是没人看到……, ...
- input file 在开发中遇到的问题 类似ajax form表单提交 input file中的文件
最近在做项目的过程中遇到个问题,在这里做个记录防止日后忘记 现今的主流浏览器由于ajax提交form表单无法把文件类型数据提交到后台,供后台处理,可是开发中由于某些原因又不得不用ajax提交文件, 为 ...
- python django Form表单
Django 拥有自己独立的表单功能块,可以完成: 1.表单的定义 2.表单的校验 3.表单的前端样式 等功能,方便我们开发,那么接下来,我们看一下表单的定义 首先我们确定我们要编写的功能,一个提供给 ...
- python中前后端通信方法Ajax和ORM映射(form表单提交)
后端从数据库获取数据给到前端: 第一种方式: admin.py文件代码: @admin.route('/showList') def show(): # 获取数据库所有文章数据,得到一个个对象 res ...
- python的Web框架,会话保持及Form表单
会话 从打开浏览器访问到关闭浏览器,这就是一次会话. cookie 技术 cookie是保存在浏览器的,安全度比较低. # 设置cookie范式,在view中设置 def index(request) ...
随机推荐
- reshape
reshape 编辑 reshape是一种函数,函数可以重新调整矩阵的行数.列数.维数.在matlab命令窗口中键入doc reshape或help reshape即可获得该函数的帮助信息. B = ...
- ES6函数增强
函数参数可以拥有默认值.调用函数时,如果没有进行相应的实参传递,参数就会使用默认值.怎么给参数提供默认值呢?很简单,声明函数时候,给形参赋一个值就可以了,这个值就是参数的默认值. // num2拥有默 ...
- 进程间通信IPC与Binder机制原理
1, Intent隐式意图携带数据 2, AIDL(Binder) 3, 广播BroadCast 4, 内容提供者ContentProvider 5,Messager(内部通过binder实现) 6, ...
- [IOI2018]组合动作——构造
题目连接: [IOI2018]combo 题目大意:有一个未知的长度为n的字符串$T$,只包含$A,B,X,Y$四个字符且首字母只出现一次,每一次你可以询问一个长度不超过$4n$的字符串$S$,交互库 ...
- SpringBoot整合ssm
1.创建工程 使用idea可以快速创建SpringBoot的工程 这里选择常用的类库,SpringBoot将各种框架类库都进行了封装,可以减少pom文件中的引用配置: 比如Spring和Mybatis ...
- BZOJ 4326 运输计划
二分答案+树链剖分+树上差分 我们假设x是最小的花费,可以想到给定x,所有运输计划中花费大于x的计划必须经过虫洞,且最长的一条的花费减去虫洞所在边的花费要小于等于x 那么对于x,虫洞所在的位置肯定是确 ...
- 【XSY2535】整数 NTT
题目描述 问有多少个满足以下要求的\(k\)进制数: 1.每个数字出现的次数不超过\(n\) 2.\(0\)没有出现过 3.若\(g_{i,j}=0\),则\(i\)不能出现恰好\(j\)次. 两次询 ...
- github 快速部署
在github上 新建一个项目后,并且未提交任何代码,会有一个页面提示我们如何快速部署.在此备份一下那个页面 Quick setup — if you’ve done this kind of thi ...
- Github Desktop 克隆新项目 Authentication failed. You may not have permission to access the repository or the repository may ha
原来:ssh://git@github.com/xxx.git 改成:https://git@github.com/xxx.git
- [POI2007]ODW-Weights(贪心)
在byteotian公司搬家的时候,他们发现他们的大量的精密砝码的搬运是一件恼人的工作.公司有一些固定容量的容器可以装这些砝码.他们想装尽量多的砝码以便搬运,并且丢弃剩下的砝码.每个容器可以装的砝码数 ...