python django 表单自动化_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:

Title

添加用户

{% csrf_token %}

用户名: {{ form.username }} {{ form.errors.username.0 }}

密码: {{ form.password }} {{ form.errors.password.0 }}

{#

#}

{# ip: {{ form.ip }} {{ form.errors.ip.0 }}#}

{#

#}

用户类型: {{ form.ut_id }} {{ form.errors.ut_id.0 }}

知识点: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})

Title

编辑用户

{% csrf_token %}

用户名: {{ form.username }} {{ form.errors.username.0 }}

密码: {{ form.password }} {{ form.errors.password.0 }}

{#

#}

{# ip: {{ form.ip }} {{ form.errors.ip.0 }}#}

{#

#}

用户类型: {{ form.ut_id }} {{ form.errors.ut_id.0 }}

通过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

Title

{% csrf_token %}

用户名:{{ form.user }}

密码:{{ form.password }}

邮箱:{{ form.email }}

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";

// v[0]

$('#f1 input[name="'+k+'"]').after(tag);

})

}

}

})

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值