渲染模块

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

reponse 数据 json 与 browser 两种渲染方式

浏览器 和 Postman 请求结果渲染数据的方式不一样

# 内置渲染器
# 可以根据用户请求 URL 或 用户可接受的类型,筛选出合适的 渲染组件。
# 显示json格式:JSONRenderer
http://127.0.0.1:8000/test/?format=json
http://127.0.0.1:8000/test.json # 默认显示格式:BrowsableAPIRenderer(可以修改它的html文件)
http://127.0.0.1:8000/test/?format=admin
http://127.0.0.1:8000/test.admin # 表格方式:AdminRenderer
http://127.0.0.1:8000/test/?format=form
http://127.0.0.1:8000/test.form # form表单方式:HTMLFormRenderer
http://127.0.0.1:8000/test/?format=form
http://127.0.0.1:8000/test.form

渲染模块的效果

postman 测试

浏览器渲染

未提供浏览器渲染时

源码分析

入口 dispatch 中的 self.response = self.finalize_response(request, response, *args, **kwargs)

rest_framework.views.APIView#dispatch

    def dispatch(self, request, *args, **kwargs):
"""
`.dispatch()` is pretty much the same as Django's regular dispatch,
but with extra hooks for startup, finalize, and exception handling.
"""
self.args = args
self.kwargs = kwargs
# 请求模块
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate? try:
self.initial(request, *args, **kwargs) # Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc:
response = self.handle_exception(exc) # 渲染模块 -- drf 渲染模块入口
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response

rest_framework.views.APIView#finalize_response

    def finalize_response(self, request, response, *args, **kwargs):
"""
Returns the final response object.
"""
# Make the error obvious if a proper response is not returned
assert isinstance(response, HttpResponseBase), (
'Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` '
'to be returned from the view, but received a `%s`'
% type(response)
) if isinstance(response, Response):
if not getattr(request, 'accepted_renderer', None):
# 获得解析类 (从这里再进入)
neg = self.perform_content_negotiation(request, force=True)
request.accepted_renderer, request.accepted_media_type = neg response.accepted_renderer = request.accepted_renderer
response.accepted_media_type = request.accepted_media_type
response.renderer_context = self.get_renderer_context() # Add new vary headers to the response instead of overwriting.
vary_headers = self.headers.pop('Vary', None)
if vary_headers is not None:
patch_vary_headers(response, cc_delim_re.split(vary_headers)) for key, value in self.headers.items():
response[key] = value return response

rest_framework.views.APIView#perform_content_negotiation

    def perform_content_negotiation(self, request, force=False):
"""
Determine which renderer and media type to use render the response.
"""
# 后去渲染类(从这里再进入)
renderers = self.get_renderers()
# 得到的就是渲染类的对象 conneg = self.get_content_negotiator() try:
return conneg.select_renderer(request, renderers, self.format_kwarg)
# 在根据 request 请求的方式再选择具体是选择哪种渲染方式,然后再调用某个方法,把数据渲染成 页面 或 json
except Exception:
if force:
return (renderers[0], renderers[0].media_type)
raise

rest_framework.views.APIView#get_renderers

    def get_renderers(self):
"""
Instantiates and returns the list of renderers that this view can use.
"""
# self.renderer_classes,当前类对象没有该属性,去找类,在类属性中找到了
return [renderer() for renderer in self.renderer_classes]
# self.renderer_classes 遍历出来是两个渲染类,类加括号会调用类的 __init__ 方法实例化

self.renderer_classes 来源

class APIView(View):
# self.renderer_classes 取到的即是配置中的 DEFAULT_RENDERER_CLASSES
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES

E:/python3-6-4/Lib/site-packages/rest_framework/settings.py 分析 settings 源码

"""
Settings for REST framework are all namespaced in the REST_FRAMEWORK setting.
For example your project's `settings.py` file might look like this: REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.TemplateHTMLRenderer',
],
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
],
} This module provides the `api_setting` object, that is used to access
REST framework settings, checking for user settings first, then falling
back to the defaults.
"""
from django.conf import settings
from django.test.signals import setting_changed
from django.utils.module_loading import import_string from rest_framework import ISO_8601 DEFAULTS = {
# Base API policies
'DEFAULT_RENDERER_CLASSES': [
# 默认提供了这两种渲染方式
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
# ...
}
# ...

如何自定义配置使用渲染类

得知我们可以在自己的 settings 文件中这样来配置它的解析类(全局配置)

REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [ # 全局配置的解析方式,所有视图类都会受这个影响
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer', # 这个是给浏览器渲染用的,没有时浏览器渲染会报错
],
}
  • 在 settings.py 中配置 DEFAULT_RENDERER_CLASSES 完成的是全局配置,所有接口统一处理

  • 如果只有部分接口要做特殊化处理,可以使用局部配置

    # 写成类属性就可以变成局部配置了
    from rest_framework.renders import JSONRenderer class Test2(APIView):
    renderer_classes = [JSONRenderer,] # 必须是以一个可迭代类型(for ... 遍历它了) def get(self, request, *args, **kwargs):
    return Response("drf get ok 2") def post(self, request, *args, **kwargs):
    return Response("drf post ok 2")

查找顺序:自定义视图类(局部) => APIView 视图类 => 自定义 drf 配置(全局) => drf 默认配置

自定义渲染模块

视图类

from rest_framework.renderers import  TemplateHTMLRenderer

class BookDetailView(APIView):
renderer_classes = [TemplateHTMLRenderer]
def get(self,request,pk):
book_obj = models.Book.objects.filter(pk=pk).first()
bs = BookSerializers(book_obj,many=False)
return Response(bs.data,template_name='aa.html')

aa.html

<!DOCTYPE html>
<html lang="en">
<head> <title>Title</title>
</head>
<body>
{{ title }}
{{ publishDate }}
</body>
</html>

Django-djangorestframework-渲染模块的更多相关文章

  1. DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render

    DRF框架    全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...

  2. Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基础文件配置,Web框架的本质,服务器程序和应用程序(wsgiref服务端模块,jinja2模板渲染模块)的使用

    Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基 ...

  3. Django(51)drf渲染模块源码分析

    前言 渲染模块的原理和解析模块是一样,drf默认的渲染有2种方式,一种是json格式,另一种是模板方式. 渲染模块源码入口 入口:APIView类中dispatch方法中的:self.response ...

  4. drf框架 - 请求模块 | 渲染模块

    Postman接口工具 官方 https://www.getpostman.com/ get请求,携带参数采用Params​post等请求,提交数据包可以采用三种方式:form-date.urlenc ...

  5. 第二章、drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 (详细版)

    目录 drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 Postman接口工具 drf框架 注册rest_framework drf框架风格 drf请求生命周期 请求模块 ...

  6. drf框架概况-resful接口规范-请求模块-渲染模块-Postman-drf请求生命周期

    drf框架 全称:django-rest- framework 知识点: """ 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码-基于restful ...

  7. 3) drf 框架生命周期 请求模块 渲染模块 解析模块 自定义异常模块 响应模块(以及二次封装)

    一.DRF框架 1.安装 pip3 install djangorestframework 2.drf框架规矩的封装风格 按功能封装,drf下按不同功能不同文件,使用不同功能导入不同文件 from r ...

  8. django-rest-framework-源码解析002-序列化/请求模块/响应模块/异常处理模块/渲染模块/十大接口

    简介 当我们使用django-rest-framework框架时, 项目必定是前后端分离的, 那么前后端进行数据交互时, 常见的数据类型就是xml和json(现在主流的是json), 这里就需要我们d ...

  9. drf路由分发、解析/渲染模块配置、使用admin、自动序列化配置

    目录 drf路由分发配置 解析模块配置 渲染模块配置 浏览器渲染打开 浏览器渲染关闭 结论 drf使用后台admin drf序列化模块 serializers.py: views.py:单查群查 测试 ...

  10. django自带的django.core.mail模块实现发邮件的功能

    django自带了一个模块,可以实现发邮件的功能.如果项目开发遇到需要发邮件进行验证的时候可以用到. 1.先要准备发件人 发邮件需要使用SMTP.SMTP是什么呢? 简单邮件传输协议(Simple M ...

随机推荐

  1. hive 调优(一)coding调优

    本人认为hive是很好的工具,目前支持mr,tez,spark执行引擎,有些大公司原来封装的sparksql,开发py脚本,但是目前hive支持spark引擎(不是很稳定,建议Tez先),所以离线还是 ...

  2. Echarts 设置 图标 默认平铺 数据为零时绘画

    好久没写了 最近接了一个统计的功能  以前写的都是一些最基础的统计 废话少说  我先把自己遇到的问题列出来 仅供参考 __________________我是分割线__________________ ...

  3. TypeError: Data location must be "memory" for return parameter in function, but none was given.

      在用truffle编译智能合约时,报错 TypeError: Data location must be "memory" for return parameter in fu ...

  4. 《Flutter 实战》开源电子书

    <Flutter 实战>开源电子书 转 https://blog.csdn.net/OQjya206rsQ71/article/details/86619630   关于 Flutter ...

  5. OS X的CAOpenGLLayer中如何启用OpenGL3.2 core profile

    在OS X的openGL编程中,我们有时为了想在自己的OpenGL图层上再加些自己的某些涂层,必须得用CAOpenGLLayer而不是NSOpenGLView,由于在NSOpenGLView上添加任何 ...

  6. linux:解决SSH连接Linux超时自动断开

    用SSH登录到Linux的时候,由于默认的连接超时时间很短,经常断开! 1.修改文件 # vi /etc/ssh/sshd_config 2.重启sshd服务 # /etc/init.d/sshd r ...

  7. QPixmap QImage 相互转化

    QPainter p(this); QPixmap pixmap; pixmap.load("E:\\参考文件\\image\\1.jpg"); //QPixmap->QIm ...

  8. Build Telemetry for Distributed Services之OpenTracing项目

    中文文档地址:https://wu-sheng.gitbooks.io/opentracing-io/content/pages/quick-start.html 中文github地址:https:/ ...

  9. Python3 继承

    继承的好处:子类实现父类的全部功能 1.单继承 若父类和子类有共同的方法或属性,则子类对父类方法或属性进行覆盖 class ClassA: def __init__(self): self.a = ' ...

  10. Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.5:test

    解决方法: 打包跳过测试有两种方法 一是命令行 mvn clean package -Dmaven.test.skip=true 二是写入pom文件 <plugin> <groupI ...