• DAY 64 drf02


    1 web开发模式:前后端分离(接口,drf),前后端混合(dtl)
    jsp,JavaScript
       
    2 api接口
    -接口,后端接口:给一个地址,向地址发送请求,可以返回json格式数据
    3 restful规范
    -10条:只是一个规范,不强制,所以公司有自己的规则
       -使用https:http+ssl
       -路径中带api标识
       -路径中带版本号
       -尽量用名词加复数
       -通过请求方式来决定操作(get获取时间)
       -返回中带状态码(json数据带状态码:自己定义的,http响应中带状态码)
       -返回结果中带错误信息
       -请求地址中带查询条件
       -响应结果中带链接
    4 postman的使用(接口测试)
    -模拟发送http请求,携带数据(请求地址,请求头,请求体,编码格式)
       -快速把接口导入导出    

    5 drf:djangorestframework,只针对于django,app,让我们快速的写接口,render,redirect了,只返回给前端json格式数据,前端可以是web,可以是app,可以是小程序



    6 bbs作业
    -修改头像
      -不能使用update,要使用对象.save
       -是否发送邮件
      -只需要在Userinfo表加一个字段即可

    补充:
    -在公司的开发环境
      -windows:远程连接linux开发
           -乌班图。。。(图形化界面的linux)
           -mac
          -

    0 drf快速使用

    0.1 views.py

    from rest_framework.viewsets import ModelViewSet
    from app import models
    from app.serializer import  BookSerializer
    class BookView(ModelViewSet):
       serializer_class =BookSerializer
       queryset = models.Book.objects.all()

    0.2 serializer.py

    from rest_framework.serializers import ModelSerializer
    from app import models
    class BookSerializer(ModelSerializer):
       class Meta:
           model = models.Book
           fields = '__all__'

    0.3 urls.py

     

    from rest_framework.routers import SimpleRouter
    from app import views

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

    0.4 在setting的app中配置

    INSTALLED_APPS = [
       'rest_framework'
    ]

    0.5 models.py

    class Book(models.Model):
       name = models.CharField(max_length=32)
       publish = models.CharField(max_length=32)
       price = models.IntegerField()

     

    1 CBV源码分析和APIView源码分析

     

    1.1 cbv执行流程

        path('test/',views.TestView.as_view()),
       # path('test/',View类的as_view内部有个view闭包函数内存地址),
       '''
      1 path的第二个参数是:View类的as_view内部有个view闭包函数内存地址
      2 一旦有请求来了,匹配test路径成功
      3 执行第二个参数view函数内存地址(requset)
      4 本质执行了self.dispatch(request)
      5 通过反射去获得方法(如果是get请求,就是get方法)
        if request.method.lower() in self.http_method_names:
          handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
      6 执行get方法,传入参数
      handler(request, *args, **kwargs)
      '''

    1.2 APIView的执行流程

        # path('test/',APIView类的as_view内部是用了View的as_view内的view闭包函数),
       '''
      1 path的第二个参数是:APIView类的as_view内部是用了View的as_view内的view闭包函数
      2 一旦有请求来了,匹配test路径成功
      3 执行第二个参数view函数内存地址(requset),还是执行View的as_view内的view闭包函数,但是加了个csrf_exempt装饰器
      4 所以,继承了APIView的所有接口,都没有csrf的校验了 (*****************)
      5 执行self.dispatch(request)----》APIView类的
          def dispatch(self, request, *args, **kwargs):
              # 以后所有的request对象,都是****新的request对象***,它是drf的Request类的对象
              request = self.initialize_request(request, *args, **kwargs)
              self.request = request
              try:
                  #整个drf的执行流程内的权限,频率,认证
                  self.initial(request, *args, **kwargs)
                  if request.method.lower() in self.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)
       
              except Exception 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)
    ##返回的request对象是drf   Request类的request对象
    def initialize_request(self, request, *args, **kwargs):
       return Request(
           request,
           parsers=self.get_parsers(),
           authenticators=self.get_authenticators(),
           negotiator=self.get_content_negotiator(),
           parser_context=parser_context
      )
    ### *******以后,在视图类中使用的request对象已经不是原来的request对象了,现在都是drf的request对象了



    #####你需要记住的
    -0 所有的csrf都不校验了
    -1 request对象变成了新的request对象,drf的request对象
       -2 执行了权限,频率,认证
       -3 捕获了全局异常(统一处理异常)
       -4 处理了response对象,如果浏览器访问是一个样,postman访问又一个样
       -5 以后,在视图类中使用的request对象已经不是原来的request对象了,现在都是drf的request对象了
     

     

    2 Request对象分析

    1 django 原生的Request:django.core.handlers.wsgi.WSGIRequest
    2 drf的Request:rest_framework.request.Request

    3 drf的request对象内有原生的request
    request._request:原生的Request
    4 在视图类中使用
    request.method 拿到的就是请求方式,
    正常拿,应该request._request.method
    5 如何实现这种操作?
    -对象.属性会触发 类的__getattr__方法


    6 drf的Request类重写了__getattr__
    def __getattr__(self, attr):
    try:
    # 去原生的request反射属性
    return getattr(self._request, attr)
    except AttributeError:
    return self.__getattribute__(attr)


    7 虽然视图类中request对象变成了drf的request,但是用起来,跟原来的一样,只不过它多了一些属性
    -request.data #post请求提交的数据,不论什么格式,都在它中
    -requst.query_params# get请求提交的数据(查询参数)


    8 重点记住:
    -drf的request对象用起来跟原来一样(重写了__getattr__)
    -request.data #post请求提交的数据,不论什么格式,都在它中
    -requst.query_params# get请求提交的数据(查询参数)

     

    3 序列化器的作用

    1 序列化:把python中的对象转成json格式字符串
    2 反序列化:把json格式字符串转成python中的对象


    3 注意:drf的序列化组件(序列化器)
    把对象(Book,queryset对象)转成字典
    因为有字典,直接丢到Response中就可以了

     

    4 序列化器的使用

    1 写一个序列化的类,继承Serializer
    class BookSerializer(serializers.Serializer):
    # 在这里写要序列化的字段
    # 序列化字段类(有很多,常用的就几个,等同于models中的字段类)
    # 字段类,有很多字段参数()
    name = serializers.CharField()
    price = serializers.IntegerField()
    # publish = serializers.CharField()
    2 在类中写要序列化的字段
    name = serializers.CharField()
    price = serializers.IntegerField()
    3 在视图类中使用(实例化)
    book_list = models.Book.objects.all() book_ser=BookSerializer(instance=book_list,many=True)
    4 得到序列化后的数据,返回
    book_ser.data

    5 字段参数,source,指定要序列化表中的哪个字段

     

    4.2 source

    1 指定要序列化的字段(数据表中字段)
    publish = serializers.CharField(source='publish.city')

    2 用的最多:只有一个字段(也可以跨表)

     

    4.2 SerializerMethodField

    1 用的最多,跨表查(要么是列表,要么是字典)
    publish=serializers.SerializerMethodField()
    def get_publish(self,obj):
    print(obj)
    # return {'name':'sss','city':'sss'}
    return {'name':obj.publish.name,'city':obj.publish.city}

    4.3 在模型表中写方法

    # 表模型中写的
    def publish_name(self):
    return {'name':self.publish.name,'city':self.publish.city}

    @property
    def author_list(self):
    return [{'name':author.name,'age':author.age,'id':author.nid} for author in self.authors.all()]

    #序列化类中
    # publish = serializers.CharField(source='publish_name')
    publish_name = serializers.DictField()
    author_list=serializers.ListField()

     

    补充

    1 装饰器函数 csrf_exempt
    @csrf_exempt
    def test():
       pass

    本质就是
    test=csrf_exempt(test)

     

  • 相关阅读:
    企业财务分析一头雾水?有了这个财务报表工具,问题一键解决
    解决wamp 3.0.6 访问路径出现 403 错误
    解决wamp 3.0.6 访问路径出现 403 错误
    解决wamp 3.0.6 访问路径出现 403 错误
    区间树
    区间树
    区间树
    区间树
    阿里云弹性裸金属服务器-神龙架构(X-Dragon)揭秘
    阿里云弹性裸金属服务器-神龙架构(X-Dragon)揭秘
  • 原文地址:https://www.cnblogs.com/DEJAVU888/p/14893729.html
Copyright © 2020-2023  润新知