FBV & CBV
FBV (Function-Based-View):在视图里使用函数处理请求
CBV (Class-Based-View):在视图里使用类处理请求
# views.py
from django.http import HttpResponse
from django.views import View
class MyView(View):
def get(self, request):
return HttpResponse('OK, get')
def post(self, request):
return HttpResponse('OK, post')
# Django的url是将一个请求分配给可调用的函数的,而不是一个class。
# 针对这个问题,class-based view提供了一个as_view()静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()方法,dispatch()方法会根据request的method的不同调用相应的方法来处理request(如get() , post()等)。
# 到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。
# urls.py
# urls.py
from django.conf.urls import url
from myapp.views import MyView
urlpatterns = [
url(r'^index/$', MyView.as_view()),
]
- 类的 属性 可以通过两种方法设置
(1) 常见的Python的方法,可以被子类覆盖。
from django.http import HttpResponse
from django.views import View
class GreetingView(View):
name = "yuan"
def get(self, request):
return HttpResponse(self.name)
# You can override that in a subclass
class MorningGreetingView(GreetingView):
name= "alex"
(2) url中设置类的属性
urlpatterns = [
url(r'^index/$', GreetingView.as_view(name="egon")),
]
应用:登录验证
----------------应用:登录验证
继承:
单继承:
# 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(request.session['username'])
写一个类继承VIEW 调用View 的dispath 函数之前做一个 session验证
多继承:
# 多继承方式:
# 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(request.session['username'])
和上面的方法原理相同, 自己写的类BaseView不继承任何类, 然后主类 继承 自己写的类 和 View 类,BaseView中的super方法 会找到 View 中的dispath
装饰器:
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 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) # 无效
def post(self,request,*args,**kwargs):
return HttpResponse(request.session['username'])
要注意俩点:
1:用的 CBV 的话 需要导入 from django.utils.decorators import method_decorator 之后@method_decorator(auth)
放在函数名上, 如果放在类上需要加个参数 @method_decorator(auth,name='get') ,说明是 给 get函数使用
2:但是django有个BUG 装饰器方法都会出现 CSRF问题 ,所以
需要写一个dispath方法 直接调用VIEW里面的 dispath 进行反射@method_decorator(auth) 放在 dispath上面
serializers序列化
-
json.dumps()
:将字典转为字符串 -
serializers.serialize()
:将QuerySet等类型转为字符串
方式一:
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 不能对 QuerySet 类型进行处理, 所以 要使用 serializers.serialize ;但是处理结果往往不太理想
方式二:
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}
]
所以我们可以 用list 将QuerySet 类型转变为List类型
问题:对json.dumps做定制:
如果要json的列表中有不能处理的字段类型,比如datetime,date
那么就需要帮它们转换一下,
在json.dumps 的命令中 可以多增加一个参数,cls=一个类
这个类继承 json.JSONEncoder,如下
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)
就可以帮助我们处理 datetime,date类型了,其他类型,当然也可以,修改类里面就ok
网友评论