•基于Django
先创建一个django项目,在项目中创建一些表,用来测试rest framework的各种组件
class UserInfo(models.Model): """用户信息表""" user = models.CharField(max_length=32) pwd = models.CharField(max_length=32) class UserToken(models.Model): """用户token表""" user = models.OneToOneField(to="UserInfo", on_delete=models.CASCADE) token = models.CharField(max_length=64) class Courses(models.Model): """ 课程表 """ name = models.CharField(verbose_name="课程名称", max_length=32) course_img = models.CharField(verbose_name="课程图片", max_length=64) level_choices = ( (1, "初级"), (2, "中级"), (3, "高级"), ) level = models.IntegerField(verbose_name="难度", choices=level_choices, default=1) def __str__(self): return self.name class CourseDetail(models.Model): """课程详细表""" course = models.OneToOneField(to="Courses", on_delete=models.CASCADE) slogan = models.CharField(verbose_name="口号", max_length=255) why = models.CharField(verbose_name="为什么要学", max_length=255) recommend_courses = models.ManyToManyField(verbose_name="推荐课程", to="Courses", related_name="rc") # related_name设置反向查询的字段,有多个关联时指定某个字段进行反向查询 def __str__(self): return "课程详细:" + self.course.title class Chapter(models.Model): """ 课程章节表 """ num = models.IntegerField(verbose_name="章节") name = models.CharField(verbose_name="章节名称", max_length=32) course = models.ForeignKey(verbose_name="所属课程", to="Courses", related_name='coursechapters', on_delete=models.CASCADE) def __str__(self): return self.name
from django.contrib import admin from django.urls import path, include, re_path urlpatterns = [ path('admin/', admin.site.urls), re_path(r'^api/(?P<version>w+)/', include("api.urls")), ]
from django.urls import re_path from api.views import courses, account, micro urlpatterns = [ re_path(r'^courses/$', courses.CoursesView.as_view({"get": "list"})), re_path(r'^courses/(?P<pk>d+)/', courses.CoursesView.as_view({"get": "retrieve"})), re_path(r'^micro/$', micro.MicroView.as_view({"get": "list"})), re_path(r'^login/$', account.LoginView.as_view()), ]
•基本流程
请求到来之后,都要执行dispatch方法,dispatch方法根据请求方式不同触发不同的方法,返回不同的内容
url.py
from django.conf.urls import url, include from api.views import TestView urlpatterns = [ url(r'^test/', TestView.as_view()), ]
views.py
from rest_framework.views import APIView from rest_framework.response import Response class TestView(APIView): def dispatch(self, request, *args, **kwargs): """ 请求到来之后,都要执行dispatch方法,dispatch方法根据请求方式不同触发 get/post/put等方法 注意:dispatch方法有好多好多的功能 """ return super().dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): return Response('GET请求,响应内容') def post(self, request, *args, **kwargs): return Response('POST请求,响应内容') def put(self, request, *args, **kwargs): return Response('PUT请求,响应内容')
•路由系统
a.半自动路由
from django.contrib import admin from django.urls import include, re_path from api.views import courses urlpatterns = [ re_path(r'^courses/$', courses.CoursesView.as_view({'get': 'list', 'post': 'create'})), re_path(r'^courses/(?P<pk>d+)/', courses.CoursesView.as_view( {'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})), ]
# -*- coding:utf-8 -*- from rest_framework.viewsets import ModelViewSet from rest_framework import serializers from api import models class UserSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class UserViewSet(ModelViewSet): queryset = models.UserInfo.objects.all() serializer_class = UserSerializer
b.全自动路由
from django.conf.urls import url, include from rest_framework import routers from api.views import users router = routers.DefaultRouter() router.register(r'users', users.UserViewSet) urlpatterns = [ url(r'^', include(router.urls)), ]
from rest_framework.viewsets import ModelViewSet from rest_framework import serializers from api import models class UserSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class UserViewSet(ModelViewSet): queryset = models.UserInfo.objects.all() serializer_class = UserSerializer
•视图系统
a.ModelViewSet自定义URL
from django.urls import include, re_path from api.views import courses urlpatterns = [ re_path(r'^courses/$', courses.CoursesView.as_view({'get': 'list', 'post': 'create'})), re_path(r'^courses/(?P<pk>d+)/', courses.CoursesView.as_view( {'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})), ]
# -*- coding:utf-8 -*- from rest_framework.viewsets import ModelViewSet from rest_framework import serializers from api import models class UserSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class UserViewSet(ModelViewSet): queryset = models.UserInfo.objects.all() serializer_class = UserSerializer
b.ModelViewSet(rest framework路由)
from django.conf.urls import url, include from rest_framework import routers from api.views import users router = routers.DefaultRouter() router.register(r'users', users.UserViewSet) urlpatterns = [ url(r'^', include(router.urls)), ]
from rest_framework import viewsets from rest_framework import serializers from api import models class UserSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class UserViewSet(viewsets.ModelViewSet): queryset = models.UserInfo.objects.all() serializer_class = UserSerializer
•版本控制
基于url的正则方式传入版本参数进行版本控制:/v1/girls/
settings.py
REST_FRAMEWORK = { 'DEFAULT_VERSION': 'v1', # 默认版本 'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本 'VERSION_PARAM': 'version' # 参数,URL中获取值的key }
urls.py
from django.urls import path, include, re_path
urlpatterns = [ re_path(r'^api/(?P<version>w+)/', include("api.urls")), ]
单个视图设置版本
views.py
# -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.versioning import URLPathVersioning class TestView(APIView): versioning_class = URLPathVersioning def get(self, request, *args, **kwargs): # 获取版本 print(request.version) # 获取版本管理的类 print(request.versioning_scheme) return Response('GET请求,响应内容')
全局设置
settings.py
REST_FRAMEWORK = { "DEFAULT_VERSIONING_CLASS": 'rest_framework.versioning.URLPathVersioning', "ALLOWED_VERSIONS": ['v1', 'v2'], # 允许的版本 "VERSION_PARAM": 'version', # 参数 "DEFAULT_VERSION": 'v1', # 默认版本 }
•解析器(parser)
根据请求头content-type选择对应的解析器处理请求体内容
a.只处理请求头content-type为application/json的请求体
views.py
# -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import JSONParser class TestView(APIView): parser_classes = [JSONParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 获取请求的值,并使用对应的JSONParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST)return Response('POST请求,响应内容')
b. 只处理请求头content-type为application/x-www-form-urlencoded 的请求体
views.py
# -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import FormParser class TestView(APIView): parser_classes = [FormParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 获取请求的值,并使用对应的FormParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) return Response('POST请求,响应内容')
c. 只处理请求头content-type为multipart/form-data的请求体
views.py
# -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import MultiPartParser class TestView(APIView): parser_classes = [MultiPartParser, ] def post(self, request, *args, **kwargs): print(request.content_type) # 获取请求的值,并使用对应的MultiPartParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) return Response('POST请求,响应内容')
d.只处理上传文件
views.py
# -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import FileUploadParser class TestView(APIView): parser_classes = [FileUploadParser, ] def post(self, request, filename, *args, **kwargs): print(filename) print(request.content_type) # 获取请求的值,并使用对应的FileUploadParser进行处理 print(request.data) # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值 print(request.POST) print(request.FILES) return Response('POST请求,响应内容')
e.同时使用多个Parser
views
# -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from rest_framework.parsers import JSONParser, FormParser, MultiPartParser class TestView(APIView): parser_classes = [JSONParser, FormParser, MultiPartParser, ] def post(self, request, filename, *args, **kwargs): print(request.content_type) # 当同时使用多个parser时,rest framework会根据请求头content-type自动进行比对,并使用对应parser print(request.data) return Response('POST请求,响应内容')
全局设置:
settings.py
REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.parsers.JSONParser' 'rest_framework.parsers.FormParser' 'rest_framework.parsers.MultiPartParser' ] }
•渲染器
访问url时将数据渲染出不同的格式进行显示
a.浏览器格式API+JSON
单个视图设置
views.py
# -*- coding:utf-8 -*- from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import serializers from rest_framework.renderers import JSONRenderer from rest_framework.renderers import BrowsableAPIRenderer from api import models class TestSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class CustomBrowsableAPIRenderer(BrowsableAPIRenderer): def get_default_renderer(self, view): return JSONRenderer() class TestView(APIView): renderer_classes = [CustomBrowsableAPIRenderer, ] def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all().first() ser = TestSerializer(instance=user_list, many=False) return Response(ser.data)
全局设置
settings.py
REST_FRAMEWORK = { "DEFAULT_RENDERER_CLASSES": ["rest_framework.renderers.JSONRenderer", "rest_framework.renderers.BrowsableAPIRenderer"], }