DRF 解析器和渲染器

一,DRF 解析器

根据请求头 content-type 选择对应的解析器就请求体内容进行处理。

1. 仅处理请求头content-type为application/json的请求体

from django.conf.urls import url, include
from web.views.s5_parser import TestView

urlpatterns = [
    url(r'test/', TestView.as_view(), name='test'),
]
urls.py
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)
        print(request.FILES)

        return Response('POST请求,响应内容')

    def put(self, request, *args, **kwargs):
        return Response('PUT请求,响应内容')
views.py

 2. 仅处理请求头content-type为application/x-www-form-urlencoded 的请求体

from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'test/', TestView.as_view(), name='test'),
]
urls.py

 

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)

        # 获取请求的值,并使用对应的JSONParser进行处理
        print(request.data)

        # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
        print(request.POST)
        print(request.FILES)

        return Response('POST请求,响应内容')

    def put(self, request, *args, **kwargs):
        return Response('PUT请求,响应内容')
views.py

3. 仅处理请求头content-type为multipart/form-data的请求体

from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'test/', TestView.as_view(), name='test'),
]

urls.py

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)

        # 获取请求的值,并使用对应的JSONParser进行处理
        print(request.data)
        # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
        print(request.POST)
        print(request.FILES)
        return Response('POST请求,响应内容')

    def put(self, request, *args, **kwargs):
        return Response('PUT请求,响应内容')
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/" method="post" enctype="multipart/form-data">
    <input type="text" name="user" />
    <input type="file" name="img">

    <input type="submit" value="提交">

</form>
</body>
</html>
upload.html

4. 仅上传文件

from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'test/(?P<filename>[^/]+)', TestView.as_view(), name='test'),
]
urls.py
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)

        # 获取请求的值,并使用对应的JSONParser进行处理
        print(request.data)
        # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
        print(request.POST)
        print(request.FILES)
        return Response('POST请求,响应内容')

    def put(self, request, *args, **kwargs):
        return Response('PUT请求,响应内容')
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data">
    <input type="text" name="user" />
    <input type="file" name="img">

    <input type="submit" value="提交">

</form>
</body>
</html>
upload.html

5. 同时多个Parser

当同时使用多个parser时,rest framework会根据请求头content-type自动进行比对,并使用对应parser

from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'test/', TestView.as_view(), name='test'),
]
urls.py
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, *args, **kwargs):
        print(request.content_type)

        # 获取请求的值,并使用对应的JSONParser进行处理
        print(request.data)
        # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值
        print(request.POST)
        print(request.FILES)
        return Response('POST请求,响应内容')

    def put(self, request, *args, **kwargs):
        return Response('PUT请求,响应内容')
views.py

6. 全局使用

REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES':[
        'rest_framework.parsers.JSONParser'
        'rest_framework.parsers.FormParser'
        'rest_framework.parsers.MultiPartParser'
    ]

}
settings.py
from django.conf.urls import url, include
from web.views import TestView

urlpatterns = [
    url(r'test/', TestView.as_view(), name='test'),
]
urls.py
from rest_framework.views import APIView
from rest_framework.response import Response


class TestView(APIView):
    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)
        print(request.FILES)
        return Response('POST请求,响应内容')

    def put(self, request, *args, **kwargs):
        return Response('PUT请求,响应内容')
views.py

注意: 个别特殊的值可以通过Django的request对象request._request来进行获取

 

二,DRF 渲染器

根据 用户请求URL 或 用户可接受的类型,筛选出合适的 渲染组件。
用户请求URL:

  • http://127.0.0.1:8000/test/?format=json
  • http://127.0.0.1:8000/test.json

用户请求头:

  • Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

1. json

访问URL:

  • http://127.0.0.1:8000/test/?format=json
  • http://127.0.0.1:8000/test.json
  • http://127.0.0.1:8000/test/ 
from django.conf.urls import url, include
from web.views import s11_render

urlpatterns = [
    url(r'^test/$', s11_render.TestView.as_view()),
    url(r'^test\.(?P<format>[a-z0-9]+)', s11_render.TestView.as_view()),
]
urls.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers

from rest_framework.renderers import JSONRenderer

from .. import models


class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"


class TestView(APIView):
    renderer_classes = [JSONRenderer, ]

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all()
        ser = TestSerializer(instance=user_list, many=True)
        return Response(ser.data)
views.py

2. 表格

访问URL:

  • http://127.0.0.1:8000/test/?format=admin
  • http://127.0.0.1:8000/test.admin
  • http://127.0.0.1:8000/test/ 
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers

from rest_framework.renderers import AdminRenderer

from .. import models


class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"


class TestView(APIView):
    renderer_classes = [AdminRenderer, ]

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all()
        ser = TestSerializer(instance=user_list, many=True)
        return Response(ser.data)
views.py

3. Form表单

访问URL:

  • http://127.0.0.1:8000/test/?format=form
  • http://127.0.0.1:8000/test.form
  • http://127.0.0.1:8000/test/ 
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 AdminRenderer
from rest_framework.renderers import HTMLFormRenderer

from .. import models


class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"


class TestView(APIView):
    renderer_classes = [HTMLFormRenderer, ]

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all().first()
        ser = TestSerializer(instance=user_list, many=False)
        return Response(ser.data)
views.py

4. 自定义显示模板

访问URL:

  • http://127.0.0.1:8000/test/?format=html
  • http://127.0.0.1:8000/test.html
  • http://127.0.0.1:8000/test/ 
from django.conf.urls import url, include
from web.views import s11_render

urlpatterns = [
    url(r'^test/$', s11_render.TestView.as_view()),
    url(r'^test\.(?P<format>[a-z0-9]+)', s11_render.TestView.as_view()),
]
urls.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework.renderers import TemplateHTMLRenderer

from .. import models


class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = "__all__"


class TestView(APIView):
    renderer_classes = [TemplateHTMLRenderer, ]

    def get(self, request, *args, **kwargs):
        user_list = models.UserInfo.objects.all().first()
        ser = TestSerializer(instance=user_list, many=False)
        return Response(ser.data, template_name='user_detail.html')
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {{ user }}
    {{ pwd }}
    {{ ut }}
</body>
</html>
userdetail.html

5. 浏览器格式API+JSON

访问URL:

  • http://127.0.0.1:8000/test/?format=api
  • http://127.0.0.1:8000/test.api
  • http://127.0.0.1:8000/test/ 
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 .. 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, template_name='user_detail.html')
views.py

 

注意:如果同时多个存在时,自动根据URL后缀来选择渲染器。

posted @ 2018-12-18 23:41  温而新  阅读(375)  评论(0编辑  收藏  举报