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
```
原文地址:https://www.cnblogs.com/yzm1017/p/11938726.html