django restful 请求_django学习之django restful framework(一)

在学习django restful framework之前我们要先回顾一下:

1. 开发模式

- 普通开发方式(之前我们在开发的时候前后端放在一起写,也就是说一个人会负责前端和后端的代码,这样就会导致开发的效率较低,而且如果后端开发人员的前端基础较差的话,就会导致产品的质量不是很好)

- 前后端分离(前端人员做前端,VUE,后端的人员写后端的代码,因为很多的时候通过vue都是通过json数据进行传输的,因此作为后端的人员只需要将自己的数据通过json序列化之后就可以了)

2. 后端开发

为前端提供URL(API/接口的开发)

注:永远返回HttpResponse(通过json的形式)

3. Django FBV、CBV

FBV,function base viewdefusers(request):

user_list= ['alex','oldboy']returnHttpResponse(json.dumps((user_list)))

CBV,classbase view

路由:

url(r'^students/', views.StudentsView.as_view()),

视图:from django.views importViewclassStudentsView(View):def get(self,request,*args,**kwargs):return HttpResponse('GET')def post(self, request, *args, **kwargs):return HttpResponse('POST')def put(self, request, *args, **kwargs):return HttpResponse('PUT')def delete(self, request, *args, **kwargs):return HttpResponse('DELETE')

ps:学会使用postman来模拟post请求

4. 列表生成式

class Foo:

pass

class Bar:

pass

v = []

for i in [Foo,Bar]:# 循环每个类

obj = i()# 类加括号实例化

v.append(obj)# 因此v里面就会有两个类的实例化对象

v = [item() for item in [Foo,Bar]] # 列表生成式

v其实就是一个对象列表

5. 面向对象基础知识

-封装-对同一类方法封装到类中classFile:

文件增删改查方法

Class DB:

数据库的方法-将数据封装到对象中classFile:def __init__(self,a1,a2):

self.a1=a1

self.xxx=a2defget:...defdelete:...defupdate:...defadd:...

obj1= File(123,666)

obj2= File(456,999)

PS: 扩展classRequest(object):def __init__(self,obj):

self.obj=obj

@propertydefuser(self):returnself.obj.authticate()classAuth(object):def __init__(self,name,age):

self.name=name

self.age=agedefauthticate(self):returnself.nameclassAPIView(object):defdispatch(self):

self.f2()deff2(self):

a= Auth('alex',18)

b= Auth('oldboy',18)

req=Request(b)print(req.user)

obj=APIView()

obj.dispatch()

6.CVB形式的源码分析

1.因为每个url对应的都是一个函数,也就是一个视图当代码运行到url(r'^students/', views.StudentsView.as_view())这里的时候其实就是返回一个视图,通过as_view->view返回一个视图函数2.def as_view(cls, **initkwargs)-->def view(request, *args, **kwargs);当执行self = cls(**initkwargs)这句话的时候,cls加括号也就是实例化这个类,等价于:self =StudentsView()3.下面就会执行return self.dispatch(request, *args, **kwargs)中的dispatch方法;换个方式:ret = self.dispatch(request, *args, **kwargs),returnret 也就是执行StudentsView里面的dispatch方法;执行dispatch是有返回值的,返回的值就是Httpresponse以及render,redreit等等;换句话说也就是请求进来之后直接执行dispatch,无论是什么请求进来都会执行dispatchdef dispatch(self, request, *args, **kwargs):

func= getattr(self, request.method.lower()) #通过反射拿到请求方式然后转成小写

ret = func(request, *args, **kwargs)#执行函数

returnret4.在源码中如何实现的呢?def dispatch(self, request, *args, **kwargs):if request.method.lower() inself.http_method_names:

handler=getattr(self, request.method.lower(), self.http_method_not_allowed)else:

handler=self.http_method_not_allowedreturn handler(request, *args, **kwargs)

FBV、CBV笔记说明:

CBV,基于反射实现根据请求方式不同,执行不同的方法。

原理:

url -> view方法 -> dispatch方法(反射执行其他:GET/POST/DELETE/PUT)

如果这样写呢?执行父类的方法

流程:classStudentsView(View):def dispatch(self, request, *args, **kwargs):print('before')

ret= super(StudentsView,self).dispatch(request, *args, **kwargs)print('after')returnretdef get(self,request,*args,**kwargs):return HttpResponse('GET')def post(self, request, *args, **kwargs):return HttpResponse('POST')def put(self, request, *args, **kwargs):return HttpResponse('PUT')def delete(self, request, *args, **kwargs):return HttpResponse('DELETE')

流程:

1.请求一进来先执行dispatch方法,然后执行父类的dispatch方法

2.里面的self指的是StudentsView,然后父类里面的handler = getattr(self, request.method.lower(), self.http_method_not_allowed)的self也是StudentsView,最后返回Httpresponse对象,然后将ret返回

继承:

1 继承(多个类共用的功能,为了避免重复编写):2 from django.views importView3

4

5 classMyBaseView(object):6 def dispatch(self, request, *args, **kwargs):7 print('before')8 ret = super(MyBaseView,self).dispatch(request, *args, **kwargs)9 print('after')10 returnret11

12 classStudentsView(MyBaseView,View):13

14 def get(self,request,*args,**kwargs):15 print('get方法')16 return HttpResponse('GET')17

18 def post(self, request, *args, **kwargs):19 return HttpResponse('POST')20

21 def put(self, request, *args, **kwargs):22 return HttpResponse('PUT')23

24 def delete(self, request, *args, **kwargs):25 return HttpResponse('DELETE')26

27 classTeachersView(MyBaseView,View):28

29 def get(self,request,*args,**kwargs):30 return HttpResponse('GET')31

32 def post(self, request, *args, **kwargs):33 return HttpResponse('POST')34

35 def put(self, request, *args, **kwargs):36 return HttpResponse('PUT')37

38 def delete(self, request, *args, **kwargs):39 return HttpResponse('DELETE')

View Code

7.csrf补充

7.1. django中间件

- process_request

- process_view

- process_response

- process_exception

- process_render_template

当请求到来的时候,先是执行process_request,然后再执行process_view,再进入视图函数

7.2. 使用中间件做过什么?

- 权限

- 用户登录验证

- django的csrf是如何实现?

是放在process_view方法里面的:

如果加上from django.views.decorators.csrf import csrf_exempt,csrf_exempt免除csrf验证

- 检查视图是否被 @csrf_exempt (免除csrf认证)

- 去请求体或cookie中获取token

7.3:FBV

情况一:

MIDDLEWARE=['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware','django.middleware.csrf.CsrfViewMiddleware', #全站使用csrf认证

'django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',

]from django.views.decorators.csrf importcsrf_exempt

@csrf_exempt#该函数无需认证

defusers(request):

user_list= ['alex','oldboy']returnHttpResponse(json.dumps((user_list)))

情况二:

MIDDLEWARE=['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware',#'django.middleware.csrf.CsrfViewMiddleware', # 全站不使用csrf认证

'django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',

]from django.views.decorators.csrf importcsrf_exempt

@csrf_protect#该函数需认证

defusers(request):

user_list= ['alex','oldboy']return HttpResponse(json.dumps((user_list)))

7.4:CBV

CBV小知识,csrf时需要使用

- @method_decorator(csrf_exempt)

- 在dispatch方法中(单独方法无效)

方式一:from django.views.decorators.csrf importcsrf_exempt,csrf_protectfrom django.utils.decorators importmethod_decoratorclassStudentsView(View):

@method_decorator(csrf_exempt)def dispatch(self, request, *args, **kwargs):return super(StudentsView,self).dispatch(request, *args, **kwargs)def get(self,request,*args,**kwargs):print('get方法')return HttpResponse('GET')def post(self, request, *args, **kwargs):return HttpResponse('POST')def put(self, request, *args, **kwargs):return HttpResponse('PUT')def delete(self, request, *args, **kwargs):return HttpResponse('DELETE')

方式二:from django.views.decorators.csrf importcsrf_exempt,csrf_protectfrom django.utils.decorators importmethod_decorator

@method_decorator(csrf_exempt,name='dispatch')classStudentsView(View):def get(self,request,*args,**kwargs):print('get方法')return HttpResponse('GET')def post(self, request, *args, **kwargs):return HttpResponse('POST')def put(self, request, *args, **kwargs):return HttpResponse('PUT')def delete(self, request, *args, **kwargs):return HttpResponse('DELETE')

8.restful 规范(建议)

a. 接口开发

urlpatterns=[#url(r'^admin/', admin.site.urls),

url(r'^get_order/', views.get_order),

url(r'^add_order/', views.add_order),

url(r'^del_order/', views.del_order),

url(r'^update_order/', views.update_order),

]defget_order(request):return HttpResponse('')defadd_order(request):return HttpResponse('')defdel_order(request):return HttpResponse('')defupdate_order(request):return HttpResponse('')

这样就会出现一个小问题,url会越来越多,不好维护

b. restful 规范(建议)1. 根据method不同做不同的操作,示例:

基于FBV:

urlpatterns=[

url(r'^order/', views.order),

]deforder(request):if request.method == 'GET':return HttpResponse('获取订单')elif request.method == 'POST':return HttpResponse('创建订单')elif request.method == 'PUT':return HttpResponse('更新订单')elif request.method == 'DELETE':return HttpResponse('删除订单')

基于CBV:

urlpatterns=[

url(r'^order/', views.OrderView.as_view()),

]classOrderView(View):def get(self,request,*args,**kwargs):return HttpResponse('获取订单')def post(self,request,*args,**kwargs):return HttpResponse('创建订单')def put(self,request,*args,**kwargs):return HttpResponse('更新订单')def delete(self,request,*args,**kwargs):return HttpResponse('删除订单')

get:获取;delete:删除;post:创建;put:更新

9.安装:django rest framework框架

源码分析:cbv

1.当请求进来的时候首先会通过url对应一个函数,对于cbv的方式先会调用按时as_view,再去调用view方法返回对应的视图函数,最重要的是里面的dispatch方法

2.

def dispatch(self, request, *args, **kwargs):"""`.dispatch()` is pretty much the same as Django's regular dispatch,

but with extra hooks for startup, finalize, and exception handling."""self.args=args

self.kwargs=kwargs

request= self.initialize_request(request, *args, **kwargs)

self.request=request

self.headers= self.default_response_headers #deprecate?

try:

self.initial(request,*args, **kwargs)#Get the appropriate handler method

if request.method.lower() inself.http_method_names:

handler=getattr(self, request.method.lower(),

self.http_method_not_allowed)else:

handler=self.http_method_not_allowed

response= handler(request, *args, **kwargs)exceptException as exc:

response=self.handle_exception(exc)

self.response= self.finalize_response(request, response, *args, **kwargs)return self.response

在这个方法中首先request = self.initialize_request(request, *args, **kwargs),在initialize_request这个方法中封装了一个Request

returnRequest(

request,

parsers=self.get_parsers(),

authenticators=self.get_authenticators(),

negotiator=self.get_content_negotiator(),

parser_context=parser_context

)

这里面的request是原生的request,里面的authenticators返回的是一个对象列表:接下来我们进入get_authenticators()这个方法中去:return [auth() for auth in self.authentication_classes],返回的是一个列表生成式,也就是认证类的对象

因此执行了request = self.initialize_request(request, *args, **kwargs)这句话之后,那么这个request是一个全新的request,丰富了原生的request的内容

接下来就会执行self.initial(request, *args, **kwargs)这个方法,再去执行self.perform_authentication(request)这个方法,将新的request放入这个方法去处理:返回的是request.user

我们再看user里面是做了些什么:

def_authenticate(self):"""Attempt to authenticate the request using each authentication instance

in turn."""

for authenticator inself.authenticators:try:

user_auth_tuple=authenticator.authenticate(self)exceptexceptions.APIException:

self._not_authenticated()raise

if user_auth_tuple is notNone:

self._authenticator=authenticator

self.user, self.auth=user_auth_tuplereturnself._not_authenticated()

通过for authenticator in self.authenticators:这个循环取到认证类的对象,然后一个个的认证,最后返回一个request.user

代码示例:

1 -仅使用:2 from django.views importView3 from rest_framework.views importAPIView4 from rest_framework.authentication importBasicAuthentication5 from rest_framework importexceptions6 from rest_framework.request importRequest7

8 classMyAuthentication(object):9 defauthenticate(self,request):10 token = request._request.GET.get('token')11 #获取用户名和密码,去数据校验

12 if nottoken:13 raise exceptions.AuthenticationFailed('用户认证失败')14 return ("alex",None)15

16 defauthenticate_header(self,val):17 pass

18

19 classDogView(APIView):20 authentication_classes =[MyAuthentication,]21

22 def get(self,request,*args,**kwargs):23 print(request)24 print(request.user)25 ret ={26 'code':1000,27 'msg':'xxx'

28 }29 return HttpResponse(json.dumps(ret),status=201)30

31 def post(self,request,*args,**kwargs):32 return HttpResponse('创建Dog')33

34 def put(self,request,*args,**kwargs):35 return HttpResponse('更新Dog')36

37 def delete(self,request,*args,**kwargs):38 return HttpResponse('删除Dog')

View Code

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值