Django的轻量级JSON辅助工具集合。
项目描述
为Django提供轻量级JSON辅助工具集合。包括一个用于安全输出JSON的模板过滤器、编码和解码JSON的视图以及用于编写简单REST视图的辅助工具。
使用特殊的JSON编码器来序列化带有to_json方法的QuerySets和对象。
过滤器
您可以使用|json过滤器将对象序列化为JSON。这在生成安全JavaScript时很有用
{% load json_tag %}
<script type="application/javascript">
(function () {
var object_list = {{ object_list|json }};
// do something with object_list
})();
</script>
|json在XML或XHTML的任何位置都可以安全使用,除了双引号属性中。使用此标签而不是将json.dumps的输出直接放入HTML中很重要,因为攻击者可能会输出一个结束标签并执行XSS攻击。例如,如果我们像这样在模板中输出json.dumps("</script><script>console.log('xss'); //")
<script>
var somedata = {{ somedata_as_json|safe }};
</script>
我们得到
<script>
var somedata = "</script>
<script>
console.log('xss'); //";
</script>
这允许攻击者注入他们自己的JavaScript。通过使用JSON的unicode转义来编码关闭标签</script>,|json 标签阻止了这种情况。如果我们输出{{ somedata|json }},我们会得到
<script>
var somedata = "\u0060xscript\u0062x\u0060xscript\u0062xconsole.log(\u0027xss\u0027);//";
</script>
json_tag 还转义了单引号,这使得你可以为eslint-plugin-html等工具编写有效的JS,以及用于单引号XML或XHTML属性。
<script data-data='{{ extra|json }}'>
var somedata = JSON.parse('{{ somedata|json }}');
</script>
它还转义了和符号,以便生成有效的XML。例如,使用值foo & bar
<document><json>{{ value|json }}</json></document>
<!-- Results in valid XML:
<document><json>"foo \u0038x bar"</json></document>
-->
标签
您还可以使用{% json %}模板标签同时序列化多个对象。
要创建一个数组,使用
{% load json_tag %}
<script type="module">
const [ham, spam, eggs] = {% json ham spam eggs %};
// do something with ham, spam and eggs.
</script>
要创建一个对象,使用
{% load json_tag %}
<script type="module">
const { ham, spam, eggs } = {% json ham=user spam=author eggs=owner %};
// do something with ham, spam and eggs.
</script>
然而,如果你混合了args和kwargs,则会得到一个具有数字属性的类似数组对象,这些属性来自args,字符串属性来自kwargs。
{% load json_tag %}
<script type="module">
import assert from 'assert';
const x = {% json ham spam=author eggs=owner %};
const [ham] = Array.from(x);
const { spam, eggs, length } = x;
assert(length === 1);
const y = Array.prototype.map.call(x, v => v + 1);
assert.deepEqual(y, [ham+1]);
// do something with ham, spam and eggs.
</script>
属性从传入的args数量中填充,以允许与Array方法(如Array.prototype.map或Array.from)一起使用。您可以重写它,但这很可能会导致Array方法失败
{% load json_tag %}
<script type="module">
import assert from 'assert';
const x = {% json ham spam=author eggs=owner length='banana'%};
const [ham] = Array.from(x);
assert(typeof ham === 'undefined');
const { spam, eggs, length } = x;
assert(length === 'banana');
const y = Array.prototype.map.call(x, v => v + 1);
assert.deepEqual(y, []);
// do something with spam and eggs.
</script>
视图
JsonResponseMixin
JsonResponseMixin实现了将对象序列化为JSON响应的render_to_response方法,因此它与通用的Django视图兼容。
from django.db import models
from django.views.generic.detail import BaseDetailView
from json_tag.views import JsonResponseMixin
class Blog(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
def to_json(self):
return {
'title': self.title,
'body': self.body,
}
class BlogDetailView(JsonResponseMixin, BaseDetailView):
"""
Detail view returning object serialized in JSON
"""
model = Blog
JsonRequestMixin
JsonRequestMixin通过data()方法提供对请求数据的访问。
from django.views.generic.base import View
from json_tag.views import JsonRequestMixin:
from json_tag.http import JsonResponse
class EchoView(JsonRequestMixin, View):
def dispatch(self, *args, **kwargs):
return JsonResponse(self.data())
RestView
RestView是一个抽象类。子类应实现auth(),用于处理身份验证,以及至少一个HTTP方法。
RestView实现了OPTIONS HTTP方法,并从JsonRequestMixin和JsonResponseMixin继承。
from django.core.exceptions import PermissionDenied
from json_tag.views import RestView
from .utils import get_action
class CrazyRestView(RestView):
def auth(self, *args, **kwargs):
if not self.request.user.is_superuser:
raise PermissionDenied
def post(self, *args, **kwargs):
action = kwargs.pop('action')
action_func = get_action(action)
return self.render_to_response(action_func(self.data()))
变更日志
0.0.1 (2018-04-24)
将模块重命名为json_tag
0.0.0 (2018-04-24)
首次发布
从django-argonauts提取
{% json %}标签
转义单引号
修复travis测试