一、FBV & CBV
CBV定义
Djanggo中的请求处理方式
FBV: Function Based View
/index/ func(request)
CBV: Class Based View
/index/ class(object)--get方法/post方法
View方法
- View方法支持的http请求:
['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] - form表单提交请求:
'get', 'post' - ajax提交请求:
['get'获取, 'post'发送, 'put'增加, 'patch'增加, 'delete'删除, 'head', 'options', 'trace'] - 请求数据:用url去路由系统中找到对应的类/函数
- 函数:直接执行函数
- 类:类名()执行构造方法初始化-->执行类中的dispatch()方法-->dispatch()中拿到请求的method进行反射
dispatch方法
class A:
def f1(self):
self.f2()
class B(A):
def f2(self):
print("-->a.f2")
#关键点:找到self到底是谁,就从哪个self这个类开始找,没有就往上找
obj = B()
obj.f1()
#报错:A类中没有f2()方法
obj = A()
obj.f1()
========================
class View:
def dispatch(self):
func = getattr(self,'get')
return func(...)
def get()
print(1)
class LoginView(View):
def dispatch(self,request, *args, **kwargs):
# 可以在执行dispatch方法前后统一执行一些代码,起到装饰器的作用
print("before")
response = super(LoginView, self).dispatch(request, *args, **kwargs)
print("after")
return response
def get():
print(2)
#打印结果为2
obj = LoginView()
obj.dispatch()
对于super(B, self).dispatch()可以这样理解:super(B, self)首先找到B的父类(就是类A),然后把类B的对象self转换为类A的对象,然后“被转换”的类A对象,先调用类B中的方法,如果没有,就向上调用类A中的方法。
应用场景:登录验证
- 继承
- 单继承
- 多继承
- 装饰器:@method_decorator(auth, name='post')
#单继承方式
class BaseView(View):
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):
def get(self, request, *args, **kwargs):
return HttpResponse('Welcome! '+request.session.get('username'))
#多继承方式
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):
def get(self, request, *args, **kwargs):
return HttpResponse('Welcome! '+request.session.get('username'))
#装饰器
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')
class IndexView(View):
# @method_decorator(auth)
def get(self, request, *args, **kwargs):
return HttpResponse('Welcome! ' + request.session.get('username'))
CBV中csrf的一个小bug
@method_decorator(csrf_exempt/protect)放在类或者对应方法上面时,不起作用,目前只能放在dispatch方法上面(对该类下的所有方法起作用)
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator
class LoginView(View):
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
response = super(LoginView, self).dispatch(request, *args, **kwargs)
return response
def get(self, request, *args, **kwargs):
return render(request, 'login.html')
def post(self, request, *args, **kwargs):
user = request.POST.get('user')
pwd = request.POST.get('pwd')
if user == 'amy' and pwd == '123':
request.session['username']=user
return redirect('/index.html')
return render(request, 'login.html', {'msg':'输入错误,请重新输入!'})
二、序列化
后端向前端传送数据
传统方式
def users(request):
user_list = models.UserInfo.objects.all()
return render(request, 'users.html', {'user_list':user_list})
方式1:序列化
serializers.serialize(),不推荐使用(数据过多)
def users(request):
return render(request, 'users.html')
from django.core import serializers
def get_users(request):
user_list = models.UserInfo.objects.all()
data = serializers.serialize('json',user_list) #将queryset格式转化为json
return HttpResponse(data)
方式2:json.dumps()
def get_users(request):
user_list = models.UserInfo.objects.values()
user_list = list(user_list)
data = json.dumps(user_list)
return HttpResponse(data)
问题:对json.dumps做定制化
json.dumps()的局限性:只能处理python的数据类型,而对于date/datetime等类型就会报错
解决办法:
前提:取数据时用values()或者values_list(),保证取到的数据是json认识的类型
from django.test import TestCase
import json
from datetime import date
from datetime import datetime
class JsonCustomEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime):
return o.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(o, date):
return o.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self, o)
user_list = [
{'id':1,'user':'amy','ctime':datetime.now()},
{'id':1,'user':'bulk','ctime':datetime.now()},
]
data = json.dumps(user_list,cls=JsonCustomEncoder)
前端展示