• Django REST framework初识


    Django REST framework是一个基于django框架开发的组件,本质是一个django的app。
    不基于drf也可以实现restful规范来开发接口程序,但是使用它可以帮程序员快速开发出一个遵循restful规范的程序。

    安装

    pip3 install djangorestframework
    

    简单使用

    • settings中注册app

      INSTALLED_APPS = [
          'django.contrib.admin',
          'django.contrib.auth',
          'django.contrib.contenttypes',
          'django.contrib.sessions',
          'django.contrib.messages',
          'django.contrib.staticfiles',
          'rest_framework'
      ]
      
    • 路由, 一个路由可以对应多个操作

      from django.conf.urls import url
      from django.contrib import admin
      from api import views
      
      urlpatterns = [
          url(r'^drf/info/', views.DrfInfoView.as_view()),
      ]
      
      
    • 视图CBV,继承APIView类

      from rest_framework.views import APIView
      from rest_framework.response import Response
      
      class DrfInfoView(APIView):
      
          def get(self,request,*args,**kwargs):
              data = [
                  {'id': 1, 'title': '震惊了...', 'content': '...'},
                 
              return Response(data)
      

    这样我们就实现了一个简单的drf应用。

    DRF的应用场景

    前后端分离项目、参与为app写接口时,用drf会比较方便。
    

    drf 解析器

    解析器,根据用户请求体格式不同进行数据解析,解析之后放在request.data中。

    在进行解析时候,drf会读取http请求头 content-type:

    • 如果content-type:x-www-urlencoded,那么drf会根据 & 符号分割的形式去处理请求体。 user=wang&age=19
    • 如果content-type:application/json,那么drf会根据 json 形式去处理请求体。 {"user":"wang","age":19}

    drf 序列化

    对对象或对象列表(queryset)进行序列化操作以及表单验证的功能。

    drf的 serializers模块提供两个功能:

    • 数据校验
    • 序列化
    from django.conf.urls import url
    from django.contrib import admin
    from api import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^info/$', views.InfoView.as_view()),
        url(r'^drf/info/$', views.DrfInfoView.as_view()),
        url(r'^drf/category/$', views.DrfCategoryView.as_view()),
        url(r'^drf/category/(?P<pk>d+)/$', views.DrfCategoryView.as_view()),
    
    
        url(r'^new/category/$', views.NewCategoryViewpython.as_view()),
        url(r'^new/category/(?P<pk>d+)/$', views.NewCategoryView.as_view()),
    ]
    
    
    from rest_framework import serializers
    
    class NewCategorySerializer(serializers.ModelSerializer):
        """定义一个类,进行序列化"""
        class Meta:
            model = models.Category
            # fields = "__all__"
            fields = ['id','name']
    
    class NewCategoryView(APIView):
        
        def get(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            if not pk:
                queryset = models.Category.objects.all()
                ser = NewCategorySerializer(instance=queryset,many=True)	# 进行数据校验,many=True表示多个对象数据
                return Response(ser.data)	# 返回数据
            else:
                model_object = models.Category.objects.filter(id=pk).first()
                ser = NewCategorySerializer(instance=model_object, many=False)	# many=True表示一个对象数据
                return Response(ser.data)
    
            
        def post(self,request,*args,**kwargs):
            ser = NewCategorySerializer(data=request.data)	# post请求,对提交的数据进行序列化校验
            if ser.is_valid():
                ser.save()		# 可以直接保存到数据库中
                return Response(ser.data)
            return Response(ser.errors)
    
        
        def put(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            category_object = models.Category.objects.filter(id=pk).first()
            ser = NewCategorySerializer(instance=category_object,data=request.data)
            if ser.is_valid():
                ser.save()
                return Response(ser.data)
            return Response(ser.errors)
    
        
        def delete(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            models.Category.objects.filter(id=pk).delete()
            return Response('删除成功')
    

    序列化时,外键关联字段、choices选择如何在前端显示中文:

    1. source: 找源头,会判断是否可执行,可执行自动加 (),不用自己加 ()例如choices:source='get_status_display'

    2. depth = 1, 将外键关联的表都显示出 0--10

    3. 钩子:x1 = serializers.SerializerMethodField()

      ​ def get_x1(self, obj):

      ​ return obj.xxx

      ​ obj是当前对象。

    4. ManyToMany显示:

      tag_title = serializers.SerializerMethodField()
      
      def get_tag_title(self, obj):
          tag_obj = obj.tag.all().values('id', 'title')
      
          return tag_obj
      
    5. 如果GET显示和POST提交的字段不相同,可以再定义一个

      class FromSerializer(serializers.ModelSerializer):
          class Meta:
              model = models.Article
              fields = '__all__'
      
      

      示例:

    class NewSerializer(serializers.ModelSerializer):
    category_name = serializers.CharField(source='category.name', required=False) # required=False 表示可以不用提交数据
    status_choice = serializers.CharField(source='get_status_display', required=False)
    # x1 = serializers.SerializerMethodField()
    # x2 = serializers.SerializerMethodField()
    tag_title = serializers.SerializerMethodField()

    class Meta:
        model = models.Article
        fields = ['title', 'summary', 'content', 'category', 'category_name', 'status', 'status_choice', 'tag', 'tag_title']
        # depth = 1
    
    # def get_x1(self, obj):
    #     return obj.category.name
    #
    # def get_x2(self, obj):
    #     return obj.get_status_display()
    
    def get_tag_title(self, obj):
    
        tag_obj = obj.tag.all().values('id', 'title')
    
        return tag_obj
    ```
  • 相关阅读:
    Django ORM 进行查询操作和性能优化
    Python PIL 长文本换行,二维码,图片合成
    python 常用的资料链接
    人生苦短,我用Python
    windows下搭建Python virtualenvvirtualenvwrapper虚拟环境。
    Python 文件上传base64图片
    python实现中文转换url编码的方法
    同时装了Python3和Python2,怎么用pip?
    统计当天下单量
    Django ORM 级联删除
  • 原文地址:https://www.cnblogs.com/yzm1017/p/11938726.html
Copyright © 2020-2023  润新知