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 形式去处理请求体。
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选择如何在前端显示中文:
- 
source: 找源头,会判断是否可执行,可执行自动加 (),不用自己加 ()例如choices:source='get_status_display' 
- 
depth = 1, 将外键关联的表都显示出 0--10 
- 
钩子:x1 = serializers.SerializerMethodField()  def get_x1(self, obj):  return obj.xxx  obj是当前对象。 
- 
ManyToMany显示: tag_title = serializers.SerializerMethodField() def get_tag_title(self, obj): tag_obj = obj.tag.all().values('id', 'title') return tag_obj
- 
如果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
```

 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号