Djangorestframework前に再生

我々は最初のDjangoのリクエストのライフサイクルを見て

- 最初のミドルウェア---「ルーティング---」ビュー---「、データへのアクセスを、テンプレートを取る「ジャンゴを---入力する」Webサーバ---- WSGI協定の実現に、データは---テンプレートをレンダリング「テンプレート文字列のリターン---」あなたはブラウザでページを参照してください

ここでは、wsgireプロトコルおよびCGIプロトコルを見てみましょう

 

 

CGIは、動的なWebサイトを開発するより原始的な方法です。あなただけの静的なHTMLページはこの効果を達成することはできません、プログラムによって生成されなければならないウェブサイトの動的コンテンツを想像することができます。その後、プログラムは、クライアントの要求を受け入れる必要があるだろうし、クライアントとサーバの通信はHTTPプロトコルによって、当然のことながら、処理され、その後、クライアントに返されます。そして、私たちはクライアントの要求に対処する上で、このプログラムを見つけるでしょう、ほとんどの時間は、このようなHTTPリクエストを解析すると、作業の重複の多くになります。言い換えれば、あなたのプログラムがHTTPリクエストを解析する必要があり、私のプログラムも解決する必要があります。だから、原理を乾燥させるために、Webサーバが誕生しました。(以下は、動作モードCGIを言われます)

だから、WebサーバーがHTTP要求を解決することができ、その後のような要求処理環境の様々なパラメータに書き込まREQUEST_METHOD、PATH_INFOなどが挙げられます。それは、サーバはこの要求に対処するための適切な手続きを呼び出した後、このプログラムは、我々がアップ書きCGIプログラムです。これは、サーバーに戻す、その後、動的なコンテンツを生成するための責任があり、その後、サーバによってクライアントに転送します。通常、環境変数やパイプのプロセスを介してサーバーとCGIプログラム間の通信、。ので、非常に明確なこと、しかし一方で欠点は、要求があるたびに、サーバはフォークやexecすることを、生成するための新しいプロセスがあるたびに、コストが非常に大きいです。CGIプログラムに理由が(HTTP要求を提供する場合)、そうでPerl、C、LUA、パイソン、を含む、ほぼすべての言語で記述することができ、独立して実行することができ、スタンドアロンのプログラムです。それを呼び出すための唯一の方法をforkとexecサーバへのプログラムのようにします。

WSGI是Web Server Gateway Interface的缩写。以层的角度来看,WSGI所在层的位置低于CGI。但与CGI不同的是WSGI具有很强的伸缩性且能运行于多线程或多进程的环境下,这是因为WSGI只是一份标准并没有定义如何去实现。实际上WSGI并非CGI,因为其位于web应用程序与web服务器之间,而web服务器可以是CGI,mod_python(注:现通常使用mod_wsgi代替),FastCGI或者是一个定义了WSGI标准的web服务器就像python标准库提供的独立WSGI服务器称为wsgiref。

WSGI里的组件分为『Server』,『Middleware』和『Application』三种,其中的『Middleware』是『设计模式』里的Decorator(装饰器)。

WSGI规范在PEP-333里讲得很详细:PEP 0333 -- Python Web Server Gateway Interface v1.0 ,但我觉得比理解规范更重要的,是理解其设计目的和工作原理。

WSGI规范写得有点绕,之所以绕, 主要原因可能是没有用『类型提示(Type Hints)』,如果用强类型OOP语言的那种『Interface』和『UML』来解释会清晰很多。

实现了wsgi 协议对应的web服务器就是uwsgi,类似Java中的tomcat 。有兴趣的话可以读一下tomcat原理https://blog.csdn.net/qq_38977097/article/details/81089172

 

CBV 源码分析

原生django的视图层可以分为两类 FBV和CBV,由于djangorestframework只能够由FBV完成,所以简单来看一下FBV的源码。

 

在FBV视图里面 ,我们的路由是类加as_view(),但是我们写的类并没有这个属性或方法 ,其实是用了父类(view)的

as_view的方法,

不难看出这就是一个闭包函数,传参给view函数,这时候会走view里面的self.dispatch方法,由于对象没有,只能够走父类(view)的dispatch方法

 

 dispatch方法只是利用了反射请求方法来分发函数,至此我们对CBV源码有了一个简单认识。看懂这个将对我们理解后面的drf有极大地帮助。

 restful规范

 

  • REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
  • REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态
  • REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
  • 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
  • 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)

 

 

下面我们逐条来分析一下restful规范的设计
API与用户的通信协议,总是使用HTTPs协议

2  域名有区分

-https://api.example.com
-https://example.org/api/

3 版本
  可以放在路径中
  可以放在请求头中

4 路径,视网络上任何东西都是资源,均使用名词表示
  https://api.example.com/v1/zoos

5 通过method 区分是什么操作
  get表示获取
  post表示新增
  delete表示删除
  patch/put 表示修改

6 过滤,通过在url上传参的形式传递搜索条件

7 状态码
{"status_code":100}

8 错误处理,应返回错误信息
{"status_code":100,'msg':'登录成功'}
{"status_code":101,'msg':'用户名错误'}

9 返回结果,针对不同操作,服务器向用户返回的结果
  get获取所有资源/get获取一个资源
  127.0.0.1/api/vi/books 获取所有图书
  {"status_code":100,'msg':'获取成功',data:[{},{}]}
  127.0.0.1/api/vi/books/3 获取id为3的图书
  {"status_code":100,'msg':'获取成功',data:{name:xx,....}}
  新增数据,把新增的数据再返回
  修改了数据,返回完整的资源对象
   删除数据,返回一个空文档
10 返回结果中提供链接

{"link": {
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}

 

基于原生django开发restful的接口

from django.views import View
from app01 import models
class APIView(View):

    def dispatch(self, request, *args, **kwargs):
        #写一些频率控制的东西
        ret = super().dispatch(request, *args, **kwargs)
        return ret

class Test(APIView):
    # http_method_names=['get']
    def get(self,request, *args, **kwargs):
        return HttpResponse('ok')

 

djangorestframework

安装下载:pip install djangorestframework

 

from rest_framework.views import  APIView
class Books(APIView):
    def get(self,request):
        #request是被封装后的request,原生的request在request._request
        #如果想用原生requset中的属性,还是原来的用法,因为Request重写了__getattr__方法
        # 原生django只能处理urlencoded和formdata编码,如果是json格式,原生django是不能处理的,需要自己从body中取出来自行处理
        # request.data 不管前端传数据的编码格式是urlencoded,formdata或者是json,都从里面取值
        # request.data
        #request.query_params  是原来django原生的GET中的数据
        #self.FILES  就是上传的文件
        dic={'name':'lqz','age':30,'height':178,'wife':['liuyifei','dilireba','egon']}
        return JsonResponse(dic)

 

#在settings.py文件中添加rest_framework,这就是django的一个app。

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', 'rest_framework' ]

 

 

我们对drf的源码分析,首先我们定义一个类,这个类继承的事APIView
继承了APIView 之后:
  1 所有的请求都没有csrf的认证了
  2 在APIView中as_view本质还是调用了父类的as_view(View的as_view)
  3 as_view中调用dispatch -----》这个dispatch是APIView的dispatch

 

 

APIVIew的dispatch方法:
  1 对原生request对象做了一层包装(面向对象的封装),以后再用的request对象都新的request对象
  2 在APIView中self.initial(request, *args, **kwargs),里面有频率控制,权限控制和认证相关
  3 根据请求方法执行咱们写的视图类中的相应方法

 


这个时候视图类中方法的request对象,已经变成了封装后的request
Request类:
  1 原生的request是self._request
  2 取以post形式提交的数据,从request.data中取(urlencoded,formdata,json格式)
  3 query_params 就是原生request的GET的数据
  4 上传的文件是从FILES中取
  5 (重点)其他的属性,直接request.属性名(因为重写了__getattr__方法)

 

 

 

おすすめ

転載: www.cnblogs.com/guanlei/p/11116071.html