drf入门

result规范

# 前后端交互使用api接口---》符合某种规范---》restful规范---》写前后端分离的标准
# REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征性状态转移)。 它首次出现在2000年Roy Fielding的博士论文中。
RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中


# https://api.weibo.com/2/account/get_uid.json
# 10条内容---》
    -1 数据的安全保障--》通常使用https协议
  -2 用api关键字标识接口---》在接口中带api字眼--》让别人一看就知道这是个api接口
      -https://api.baidu.com/books
        -https://127.0.0.1:8080/api/books
        
  -3 多版本共存--->在接口地址中带版本号----都留---》尽快升级---》xx年我们就不支持xx以下版本了
          -有的人用了老版本app--》老接口v1
        -有的人用了新版本app--》新接口v2
      -https://api.baidu.com/v1/login
            -https://api.baidu.com/v2/login
    -4 数据即是资源,均使用名词(可复数)--》请求地址中尽量不出现动词
          -https://api.baidu.com/v1/users  # 获取用户,删除用户,新增用户
   
  -5 资源操作由请求方式决定-->get,post,delete ,put,patch
      -get请求是获取数据
    -post请求是新增数据
    -delete请求是删除数据
    -put请求是修改数据
    -patch请求是局部修改数据
    
  -6 请求地址中带过滤条件
      -https://api.example.com/v1/zoos?limit=10  # 返回10条数据
    -https://api.example.com/v1/books?name=西游记  # 查询名字是西游记的这本书
      
  -7 响应状态码(http的响应状态码,响应体的json数据中带状态码)
      -http的响应状态码
      -1xx:请求正在处理
      -2xx:请求成功(200,201)  200和201有什么区别?
      -3xx:重定向 (301和302有什么区别)
      -4xx:客户端错误(404:地址不存在,403:禁止了)
      -5xx:服务端错误 
    -响应体中返回json格式数据---》code,status--->也有状态码---》服务端自定义的
        -1001  :用户名错误
      -1002   :没有权限。。
      
 -8 错误处理,应返回错误信息
        -返回数据是json格式--》带状态码---》错误信息
      {
        error: "无权限操作"
        }
-9 返回数据格式符合如下规范(大部分公司不按这个)
    -多条数据返回列表
    GET /collection:返回资源对象的列表 [{name:lqz,age:19},{name:pyy,age:33}]
  -单条数据返回字典
  GET /collection/resource:返回单个资源对象 {name:lqz,age:19}
  -新增,返回新增的对象---》{name:lqz,age:19}
  POST /collection:返回新生成的资源对象
  -修改,返回修改后的对象--》{name:lqz,age:19}
  PUT /collection/resource:返回完整的资源对象
  -修改,返回修改后的对象--》{name:lqz,age:19}
  PATCH /collection/resource:返回完整的资源对象
  -删除,返回空文档
  DELETE /collection/resource:返回一个空文档  -->{code:100,msg:删除成功}
  
  
-10 返回资源中链接地址
  {
      "id": 1404376560,
      "description": "人生五十年,乃如梦如幻;有生斯有死,壮士复何憾。",
      "url": "http://blog.sina.com.cn/zaku",
      "profile_image_url": "http://tp1.sinaimg.cn/1404376560/50/0/1",
      "domain": "zaku",
  }

drf安装

>: pip3 install djangorestframework
View Code

drf封装风格

from rest_framework.views import APIView    # 完成视图
from rest_framework.response import Response  # 响应数据
from rest_framework.request import Request  # 请求数据
from rest_framework.serializers import Serializer # 序列化类
from rest_framework.settings import APISettings
from rest_framework.filters import SearchFilter  # 查询过滤器
from rest_framework.pagination import PageNumberPagination  # 分页器
from rest_framework.authentication import TokenAuthentication   # auth认证
from rest_framework.permissions import IsAuthenticated  # 权限认证
from rest_framework.throttling import SimpleRateThrottle  # 频率
 
class Test(APIView):
    def get(self, request, *args, **kwargs):
        return Response('drf get ok')

drf请求生命周期

1) 请求走的是APIView的as_view函数
 
2) 在APIView的as_view调用父类(django原生)的as_view,还禁用了 csrf 认证
 
3) 在父类的as_view中dispatch方法请求走的又是APIView的dispatch
 
4) 完成任务方法交给视图类的请求函数处理,得到请求的响应结果,返回给前台

 API源码分析

APIView类的dispatch方法中:request = self.initialize_request(request, *args, **kwargs)
# 二次封装得到def的request对象
request = self.initialize_request(request, *args, **kwargs) 点进去
 
# 在rest_framework.request.Request实例化方法中
self._request = request  将原生request作为新request的_request属性
 
# 在rest_framework.request.Request的__getattr__方法中
try:
    return getattr(self._request, attr)  # 访问属性完全兼容原生request
except AttributeError:
    return self.__getattribute__(attr)
# APIView的dispatch
  def dispatch(self, request, *args, **kwargs):
          # request是新的drf提供的request,它是由老的django的request得到的
          # 通过老request,生成一个新request,drf的Request的对象
        request = self.initialize_request(request, *args, **kwargs)
        # 把新的request,放到了视图类对象中
        self.request = request
        try:
           # 执行了三大认证(认证,权限,频率)
            self.initial(request, *args, **kwargs)
            # self.http_method_names是个列表
            if request.method.lower() in self.http_method_names:
                  # 原来dispatch的核心代码
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
            # 原来dispatch写的,但是request已经不是老request了,是新的
            response = handler(request, *args, **kwargs) # 执行视图函数的方法
        except Exception as exc:
              # 无论在三大认证过程中还是执行视图函数方法过程中,只要抛了异常,都会被捕获到
            # 处理全局异常
            response = self.handle_exception(exc)

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

 

总结

1) drf 对原生request做了二次封装,request._request就是原生request
2) 原生request对象的属性和方法都可以被drf的request对象直接访问(兼容)
3) drf请求的所有url拼接参数均被解析到query_params中,所有数据包数据都被解析到data中

 

drf快速使用

视图

from rest_framework.viewsets import ModelViewSet
from .models import Book # 模块导入使用相对导入
# from app01.models import Book # 使用绝对导入
from .serializer import BookSerializer
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

路由

from rest_framework.routers import SimpleRouter
from app01 import views

router = SimpleRouter()
router.register('books', views.BookView, 'books')
urlpatterns = [
    path('admin/', admin.site.urls),
]
urlpatterns += router.urls

序列化类(需要创建一个py文件)

from .models import Book
from rest_framework import serializers

class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'

模型

class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(decimal_places=2, max_digits=5)
    author = models.CharField(max_length=32)

 

posted @ 2022-03-29 15:59  椰子皮0oo0  阅读(59)  评论(0)    收藏  举报
1