drf框架(2)

drf框架

”“”接口:
接口规范:
drf的生命周期:
序列化组件:
三大认证:过滤,删选,排序组件
请求,响应,解析,异常
jwt:json web tooken

“”“
"""
http协议(非安全的,速度快):基于tcp之上的应用层协议
    应用层协议-
    如何交互的规范==请求与响应规范:首行 - 头 - 体
    特点:无状态.无连接,所以的请求都是从客户端到服务端,ssl(安全加密机制https)
    
wsgi协议:
原生的django启动项目。启动了server socket -wsgiref -uWSGI(项目上线,换了底层的socket,支持并发量高的)
    规定数据的解析方式:get数据,post数据 =>request=>回调的视图函数
    返回响应对象:HTTPResponse类对象,redirct,JsonPonse,render(4)
        返回的内容是有数据的,且还有响应状态码,
    
    """

restful接口规范

"""
1>一般都采用安全协议(接口都是操作数据的):https

2>提现接口的关键字:api
    https://api.oldboy.com
    
3>接口操作的数据称之为资源:采用资源名称的复数
    https://api.oldboy.com/books
    
4>接口链接中不出现操作资源的动词,通过请求方式来决定操作资源的动作
    https://api.oldboy.com/books/
    get:获取所以
    post:增加一个
    https://api.oldboy.com/books/(?P<pk>)/
    get:获取一个
    put:整体修改一个(patch局部修改一个)
    delete:删除一个
    
5>资源数据有多版本时,接口可以做版本控制,为什么有两种版本(需求请求不同,接口有不同的版本响应)
    https://api.oldboy.com/books/v1/
    https://api.oldboy.com/v2/books/
    丢在资源之前之后都可以
    
6>资源响应的限制条件:筛选、排序、限制...
    https://api.oldboy.com/books/?publish=1&ordering=-price&limit=3
    
7>响应状态码
    网络状态码:2xx | 3xx | 4xx | 5xx
    数据状态码(约定的):0 | 1 | 2
    {
        'status': 1,
    }
    -- SUCCESS(0, "查询成功")
    -- NODATA(1, "非正确,无数据,显示基本信息")
    -- FEAILED(2, "查询失败")
    
8>响应结果的信息描述:
    {
        'status': 1,
        'msg': 'login failed'
    }

9>响应的结果:get所有:所有资源 | get一个:一个资源 | post、put、patch:新增、修改的资源 | delete:不做任何返回
    {
        'status': 0,
        'msg': 'ok',
        'results': [登录的用户对象序列化结果]
    }
    
10>响应结果中有二次资源(用户头像:图片链接,用户详情:详情接口)
    要表明请求二次资源的接口

注:通过 接口文档 告诉前台传递的必要和选填参数
"""

百度测试接口

安装postman
https://www.getpostman.com/downloads/
测试接口
method: GET
url: https://api.map.baidu.com/place/v2/search
params:
ak: 6E823f587c95f0148c19993539b99295
region: 上海
query: 肯德基
output: json

原生Django实现接口

创建Django项目并设置默认app名为api,完成路由分发
# 主路由
fromdjango.conf.urlsimporturl, include
fromdjango.contribimportadmin
urlpatterns= [
   url(r'^admin/', admin.site.urls),
   url(r'^api/', include('api.urls')),
]

# api应用下的子路由
fromdjango.conf.urlsimporturl
from. importviews
urlpatterns= [
   # as_view() 本质拿到 view函数地址,
   # view内部通过dispatch分发请求给具体的(get|post|delete)方法处理请求
   # 处理完后的响应结果会一层层返回
   url(r'^books/$', views.BookView.as_view()),
   url(r'^books/(?P<pk>.*)/$', views.BookView.as_view()),
]
模型层:models.py
fromdjango.dbimportmodels
classBook(models.Model):
   name= models.CharField(max_length=64)
   price= models.DecimalField(max_digits=5, decimal_places=2)
   classMeta:
       db_table= 'old_boy_book'
       verbose_name= '书籍'
       verbose_name_plural= verbose_name
   def__str__(self):
       returnself.name
数据库迁移
>: python manage.py makemigrations
>: python manage.py migrate
后台管理:admin.py
fromdjango.contribimportadmin
from. importmodels
admin.site.register(models.Book)
admin.site.register(models.User)

# 创建超级用户
# >: python manage.py createsuperuser
视图层:views.py
fromdjango.viewsimportView
fromdjango.httpimportJsonResponse
from. importmodels
classBookView(View):
   defget(self, request, *args, **kwargs):
       pk= kwargs.get('pk')
       ifpk:  # 通过是否有主键决定获取单个或是全部资源
           book_dic_list= models.Book.objects.filter(pk=pk).values('name', 'price')
           ifnotbook_dic_list:
               returnJsonResponse({
                   'status': 2,
                   'msg': 'pk值有误',
                   'results': {}
              })
           returnJsonResponse({
               'status': 0,
               'msg': 'ok',
               'results': book_dic_list[0]
          })

       book_dic_list= models.Book.objects.all().values('name', 'price')
       ifnotbook_dic_list:
           returnJsonResponse({
               'status': 2,
               'msg': '无数据',
               'results': {}
          })
       returnJsonResponse({
           'status': 0,
           'msg': 'ok',
           'results': list(book_dic_list)
      })

视图层回顾

视图:models.py
classUser(models.Model):
   SEX_CHOICES= [
      (0, '男'),
      (1, '女'),
      (2, '哇塞')
  ]
   username= models.CharField(max_length=64)
   password= models.CharField(max_length=64)
   sex= models.IntegerField(choices=SEX_CHOICES, default=0)
   # 需要配置media工作目录与路由
   icon= models.ImageField(upload_to='icon', default='/icon/default.png')
   classMeta:
       db_table= 'old_boy_user'
       verbose_name= '用户'
       verbose_name_plural= verbose_name

   def__str__(self):
       returnself.username
media工作目录:settings.py
# MEDIA_URL = '/media/'
MEDIA_ROOT= os.path.join(BASE_DIR, 'media')
路由:主urls.py
fromdjango.conf.urlsimporturl, include
fromdjango.contribimportadmin

fromdjango.views.staticimportserve
fromdjango.confimportsettings
urlpatterns= [
   url(r'^admin/', admin.site.urls),
   url(r'^api/', include('api.urls')),
   url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
]

drf框架

安装
>: pip3 install djangorestframework
配置:settings.py
# 注册drf app
NSTALLED_APPS= [
   # ...
   'rest_framework',
]
特点:
# 具体功能在具体模块下
fromrest_framework.requestimportRequest
fromrest_framework.responseimportResponse
fromrest_framework.exceptionsimportAPIException
fromrest_framework.filtersimportOrderingFilter
fromrest_framework.viewsimportAPIView
fromrest_framework.paginationimportPageNumberPagination
fromrest_framework.settingsimportAPISettings

# 自定义drf配置 - 在自己的settings.py
REST_FRAMEWORK= {
   # 自定义修改drf的配置们
}

原生Django CBV 源码分析:View

"""
1)as_view()是入口,得到view函数地址
2)请求来了调用view函数,内部调用dispatch函数完成请求分发
3)dispatch函数将请求方式映射成视图类的同名方法,完成请求的处理,得到相应
4)再将相应的结果一层层返回
"""

drf CBV 源码分析:APIView

"""
1)as_view()是入口,得到view函数地址,在范围view函数地址时局部禁用csrf认证
2)请求来了调用view函数,内部调用(APIView类的)dispatch函数完成请求分发
3)dispatch函数 二次封装request、完成三大认证后,再将请求方式映射成视图类的同名方法,完成请求的处理,得到相应,再对相应做渲染处理
4)再将相应的结果一层层返回
"""

响应渲染模块:json和浏览器接口页面

# 入口:APIView类的dispatch函数
self.response= self.finalize_response(request, response, *args, **kwargs)
->
neg= self.perform_content_negotiation(request, force=True)
->
renderers= self.get_renderers()
->
self.renderer_classes
->
APISetting:DEFAULT_RENDERER_CLASSES
局部配置
fromrest_framework.viewsimportAPIView
fromrest_framework.responseimportResponse

fromrest_framework.renderersimportJSONRenderer
fromrest_framework.renderersimportBrowsableAPIRenderer
classUserAPIView(APIView):
   # 局部配置:只有该视图类起作用
   renderer_classes= [JSONRenderer]  # 只提供JSON数据渲染
   pass
全局配置
# drf配置
REST_FRAMEWORK= {
   # 响应的渲染模块
   'DEFAULT_RENDERER_CLASSES': [
       'rest_framework.renderers.JSONRenderer',
       'rest_framework.renderers.BrowsableAPIRenderer',
  ],
}

请求数据解析模块:json、form-data、urlencoding

# 入口:APIView类的dispatch函数
request= self.initialize_request(request, *args, **kwargs)
->
parsers=self.get_parsers()
->
self.parser_classes
->
APISetting:DEFAULT_PARSER_CLASSES
局部配置
from rest_framework.views import APIView
from rest_framework.response import Response

from rest_framework.parsers import JSONParser
from rest_framework.parsers import FormParser
from rest_framework.parsers import MultiPartParser
class UserAPIView(APIView):
    # 局部配置:只有该视图类起作用
    parser_classes = [JSONParser]  # 只提供JSON解析
    pass
全局配置
# drf配置
REST_FRAMEWORK= {
   # 响应的渲染模块
   'DEFAULT_RENDERER_CLASSES': [
       'rest_framework.renderers.JSONRenderer',
       'rest_framework.renderers.BrowsableAPIRenderer',
  ],
   # 请求数据解析模块
   'DEFAULT_PARSER_CLASSES': [
       'rest_framework.parsers.JSONParser',  # 'application/json'
       'rest_framework.parsers.FormParser',  # 'application/x-www-form-urlencoded'
       'rest_framework.parsers.MultiPartParser' # multipart/form-data
  ],
}
请求数据解析位置
# 请求的数据包:均解析到 request.data 中
# 请求的?文件参数:均解析到 request.query_params 中

响应模块

# 响应可以设置响应数据、响应网络状态码、响应头、响应数据类型等
data= {
   'status': 0,
   'msg': 'get ok',
   'results': [],
   'token': '123.12321.231'
}
returnResponse(
   data=data,
   status=status.HTTP_200_OK,
   headers={'Token': '123as.masd21.asd213sd'},
   content_type='application/json' # 默认就是application/json
)

drf框架

”“”接口:
接口规范:
drf的生命周期:
序列化组件:
三大认证:过滤,删选,排序组件
请求,响应,解析,异常
jwt:json web tooken

“”“
"""
http协议(非安全的,速度快):基于tcp之上的应用层协议
    应用层协议-
    如何交互的规范==请求与响应规范:首行 - 头 - 体
    特点:无状态.无连接,所以的请求都是从客户端到服务端,ssl(安全加密机制https)
    
wsgi协议:
原生的django启动项目。启动了server socket -wsgiref -uWSGI(项目上线,换了底层的socket,支持并发量高的)
    规定数据的解析方式:get数据,post数据 =>request=>回调的视图函数
    返回响应对象:HTTPResponse类对象,redirct,JsonPonse,render(4)
        返回的内容是有数据的,且还有响应状态码,
    
    """

restful接口规范

"""
1>一般都采用安全协议(接口都是操作数据的):https

2>提现接口的关键字:api
    https://api.oldboy.com
    
3>接口操作的数据称之为资源:采用资源名称的复数
    https://api.oldboy.com/books
    
4>接口链接中不出现操作资源的动词,通过请求方式来决定操作资源的动作
    https://api.oldboy.com/books/
    get:获取所以
    post:增加一个
    https://api.oldboy.com/books/(?P<pk>)/
    get:获取一个
    put:整体修改一个(patch局部修改一个)
    delete:删除一个
    
5>资源数据有多版本时,接口可以做版本控制,为什么有两种版本(需求请求不同,接口有不同的版本响应)
    https://api.oldboy.com/books/v1/
    https://api.oldboy.com/v2/books/
    丢在资源之前之后都可以
    
6>资源响应的限制条件:筛选、排序、限制...
    https://api.oldboy.com/books/?publish=1&ordering=-price&limit=3
    
7>响应状态码
    网络状态码:2xx | 3xx | 4xx | 5xx
    数据状态码(约定的):0 | 1 | 2
    {
        'status': 1,
    }
    -- SUCCESS(0, "查询成功")
    -- NODATA(1, "非正确,无数据,显示基本信息")
    -- FEAILED(2, "查询失败")
    
8>响应结果的信息描述:
    {
        'status': 1,
        'msg': 'login failed'
    }

9>响应的结果:get所有:所有资源 | get一个:一个资源 | post、put、patch:新增、修改的资源 | delete:不做任何返回
    {
        'status': 0,
        'msg': 'ok',
        'results': [登录的用户对象序列化结果]
    }
    
10>响应结果中有二次资源(用户头像:图片链接,用户详情:详情接口)
    要表明请求二次资源的接口

注:通过 接口文档 告诉前台传递的必要和选填参数
"""

百度测试接口

安装postman
https://www.getpostman.com/downloads/
测试接口
method: GET
url: https://api.map.baidu.com/place/v2/search
params:
ak: 6E823f587c95f0148c19993539b99295
region: 上海
query: 肯德基
output: json

原生Django实现接口

创建Django项目并设置默认app名为api,完成路由分发
# 主路由
fromdjango.conf.urlsimporturl, include
fromdjango.contribimportadmin
urlpatterns= [
   url(r'^admin/', admin.site.urls),
   url(r'^api/', include('api.urls')),
]

# api应用下的子路由
fromdjango.conf.urlsimporturl
from. importviews
urlpatterns= [
   # as_view() 本质拿到 view函数地址,
   # view内部通过dispatch分发请求给具体的(get|post|delete)方法处理请求
   # 处理完后的响应结果会一层层返回
   url(r'^books/$', views.BookView.as_view()),
   url(r'^books/(?P<pk>.*)/$', views.BookView.as_view()),
]
模型层:models.py
fromdjango.dbimportmodels
classBook(models.Model):
   name= models.CharField(max_length=64)
   price= models.DecimalField(max_digits=5, decimal_places=2)
   classMeta:
       db_table= 'old_boy_book'
       verbose_name= '书籍'
       verbose_name_plural= verbose_name
   def__str__(self):
       returnself.name
数据库迁移
>: python manage.py makemigrations
>: python manage.py migrate
后台管理:admin.py
fromdjango.contribimportadmin
from. importmodels
admin.site.register(models.Book)
admin.site.register(models.User)

# 创建超级用户
# >: python manage.py createsuperuser
视图层:views.py
fromdjango.viewsimportView
fromdjango.httpimportJsonResponse
from. importmodels
classBookView(View):
   defget(self, request, *args, **kwargs):
       pk= kwargs.get('pk')
       ifpk:  # 通过是否有主键决定获取单个或是全部资源
           book_dic_list= models.Book.objects.filter(pk=pk).values('name', 'price')
           ifnotbook_dic_list:
               returnJsonResponse({
                   'status': 2,
                   'msg': 'pk值有误',
                   'results': {}
              })
           returnJsonResponse({
               'status': 0,
               'msg': 'ok',
               'results': book_dic_list[0]
          })

       book_dic_list= models.Book.objects.all().values('name', 'price')
       ifnotbook_dic_list:
           returnJsonResponse({
               'status': 2,
               'msg': '无数据',
               'results': {}
          })
       returnJsonResponse({
           'status': 0,
           'msg': 'ok',
           'results': list(book_dic_list)
      })

视图层回顾

视图:models.py
classUser(models.Model):
   SEX_CHOICES= [
      (0, '男'),
      (1, '女'),
      (2, '哇塞')
  ]
   username= models.CharField(max_length=64)
   password= models.CharField(max_length=64)
   sex= models.IntegerField(choices=SEX_CHOICES, default=0)
   # 需要配置media工作目录与路由
   icon= models.ImageField(upload_to='icon', default='/icon/default.png')
   classMeta:
       db_table= 'old_boy_user'
       verbose_name= '用户'
       verbose_name_plural= verbose_name

   def__str__(self):
       returnself.username
media工作目录:settings.py
# MEDIA_URL = '/media/'
MEDIA_ROOT= os.path.join(BASE_DIR, 'media')
路由:主urls.py
fromdjango.conf.urlsimporturl, include
fromdjango.contribimportadmin

fromdjango.views.staticimportserve
fromdjango.confimportsettings
urlpatterns= [
   url(r'^admin/', admin.site.urls),
   url(r'^api/', include('api.urls')),
   url(r'^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
]

drf框架

安装
>: pip3 install djangorestframework
配置:settings.py
# 注册drf app
NSTALLED_APPS= [
   # ...
   'rest_framework',
]
特点:
# 具体功能在具体模块下
fromrest_framework.requestimportRequest
fromrest_framework.responseimportResponse
fromrest_framework.exceptionsimportAPIException
fromrest_framework.filtersimportOrderingFilter
fromrest_framework.viewsimportAPIView
fromrest_framework.paginationimportPageNumberPagination
fromrest_framework.settingsimportAPISettings

# 自定义drf配置 - 在自己的settings.py
REST_FRAMEWORK= {
   # 自定义修改drf的配置们
}

原生Django CBV 源码分析:View

"""
1)as_view()是入口,得到view函数地址
2)请求来了调用view函数,内部调用dispatch函数完成请求分发
3)dispatch函数将请求方式映射成视图类的同名方法,完成请求的处理,得到相应
4)再将相应的结果一层层返回
"""

drf CBV 源码分析:APIView

"""
1)as_view()是入口,得到view函数地址,在范围view函数地址时局部禁用csrf认证
2)请求来了调用view函数,内部调用(APIView类的)dispatch函数完成请求分发
3)dispatch函数 二次封装request、完成三大认证后,再将请求方式映射成视图类的同名方法,完成请求的处理,得到相应,再对相应做渲染处理
4)再将相应的结果一层层返回
"""

响应渲染模块:json和浏览器接口页面

# 入口:APIView类的dispatch函数
self.response= self.finalize_response(request, response, *args, **kwargs)
->
neg= self.perform_content_negotiation(request, force=True)
->
renderers= self.get_renderers()
->
self.renderer_classes
->
APISetting:DEFAULT_RENDERER_CLASSES
局部配置
fromrest_framework.viewsimportAPIView
fromrest_framework.responseimportResponse

fromrest_framework.renderersimportJSONRenderer
fromrest_framework.renderersimportBrowsableAPIRenderer
classUserAPIView(APIView):
   # 局部配置:只有该视图类起作用
   renderer_classes= [JSONRenderer]  # 只提供JSON数据渲染
   pass
全局配置
# drf配置
REST_FRAMEWORK= {
   # 响应的渲染模块
   'DEFAULT_RENDERER_CLASSES': [
       'rest_framework.renderers.JSONRenderer',
       'rest_framework.renderers.BrowsableAPIRenderer',
  ],
}

请求数据解析模块:json、form-data、urlencoding

# 入口:APIView类的dispatch函数
request= self.initialize_request(request, *args, **kwargs)
->
parsers=self.get_parsers()
->
self.parser_classes
->
APISetting:DEFAULT_PARSER_CLASSES
局部配置
from rest_framework.views import APIView
from rest_framework.response import Response

from rest_framework.parsers import JSONParser
from rest_framework.parsers import FormParser
from rest_framework.parsers import MultiPartParser
class UserAPIView(APIView):
    # 局部配置:只有该视图类起作用
    parser_classes = [JSONParser]  # 只提供JSON解析
    pass
全局配置
# drf配置
REST_FRAMEWORK= {
   # 响应的渲染模块
   'DEFAULT_RENDERER_CLASSES': [
       'rest_framework.renderers.JSONRenderer',
       'rest_framework.renderers.BrowsableAPIRenderer',
  ],
   # 请求数据解析模块
   'DEFAULT_PARSER_CLASSES': [
       'rest_framework.parsers.JSONParser',  # 'application/json'
       'rest_framework.parsers.FormParser',  # 'application/x-www-form-urlencoded'
       'rest_framework.parsers.MultiPartParser' # multipart/form-data
  ],
}
请求数据解析位置
# 请求的数据包:均解析到 request.data 中
# 请求的?文件参数:均解析到 request.query_params 中

响应模块

# 响应可以设置响应数据、响应网络状态码、响应头、响应数据类型等
data= {
   'status': 0,
   'msg': 'get ok',
   'results': [],
   'token': '123.12321.231'
}
returnResponse(
   data=data,
   status=status.HTTP_200_OK,
   headers={'Token': '123as.masd21.asd213sd'},
   content_type='application/json' # 默认就是application/json
)

猜你喜欢

转载自www.cnblogs.com/abdm-989/p/11872848.html