• Django Rest Framework(一)


    •基于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
    models.py
    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")),
    ]
    urls.py
    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()),
    ]
    api/urls.py

    •基本流程

    请求到来之后,都要执行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'})),
    ]
    urls.py
    # -*- 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
    views.py

    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)),
    ]
    urls.py
    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
    views.py

    •视图系统

    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'})),
    ]
    urls.py
    # -*- 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
    views.py

    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)),
    ]
    urls.py
    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
    views.py

    •版本控制

    基于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"],
    }
  • 相关阅读:
    KVM/QEMU简介
    编辑器制作的一些资源
    HRBEU ACM 图论 1006
    zoj 2001
    HRBEU equal
    zoj Integer Inquiry
    HRBEU 字符串 1003
    poj 2736
    SDUT_DP 1003
    zoj Martian Addition
  • 原文地址:https://www.cnblogs.com/zivli/p/10321771.html
Copyright © 2020-2023  润新知