写后台的时候经常需要写数据接口,这时就需要用到序列化工具, 而默认到序列化工具对 Django model 的序列化支持有限。 同时 Django 本身的序列化工具我在使用时也觉得有诸多不便,因此我尝试自己写了一个快速序列化工具,帮助我快速简单的实现数据接口。
Django Simple Serializer 是一个可以帮助开发者快速将 Django 数据或者 python data 序列化为 json|raw 数据的工具。
##为什么要用 Django Simple Serializer ?
对于序列化 Django 数据的解决方案已经有以下几种:
###django.core.serializers Django 内建序列化器, 它可以序列化 Django model query set 但无法直接序列化单独的 Django model 数据。如果你的 model 里含有混合数据 , 这个序列化器同样无法使用(如果你想直接使用序列化数据). 除此之外, 如果你想直接把序列化数据返回给用户,显然它包含了很多敏感及对用户无用对信息。 ###QuerySet.values() 和上面一样, 如果你的 model 里有 DateTimeField 或者其他特殊的 Field 以及额外数据, QuerySet.values() 同样没法工作。 ###django-rest-framework serializers django-rest-framework 是一个可以帮助你快速构建 REST API 的强力框架。 他拥有完善的序列化器,但在使用之前你需要花费一些时间入门, 并学习 cbv 的开发方式, 对于有时间需求的项目或者已经存在的项目需要增加数据接口时显然这不是最好的解决方案。 ###django simple serializer 我希望可以快速简单的序列化数据, 所以我设计了一种可以不用任何额外的配置与学习而将 Django data 或者 python data 序列化为相应的数据的简单的方式。 这就是为什么我写了 django simple serializer 。
##运行需求 Django >= 1.5
Python 2.5 及以上 (暂不支持 python 3)
##安装
Install using pip:
pip install django-simple-serializer
##使用 django simple serializer 进行开发 ###序列化 Django data 假设我们有以下 Django models :
class Classification(models.Model):
c_name = models.CharField(max_length=30, unique=True)
class Article(models.Model):
caption = models.CharField(max_length=50)
classification = models.ForeignKey(Classification, related_name='cls_art')
content = models.TextField()
publish = models.BooleanField(default=False)
使用 django simple serializer 的简单例子:
from dss.Serializer import serializer
article_list = Article.objects.all()
data = serializer(article_list)
data:
[{'read_count': 0, 'create_time': 1432392456.0, 'modify_time': 1432392456.0, 'sub_caption': u'first', 'comment_count': 0, u'id': 31}, {'read_count': 0, 'create_time': 1432392499.0, 'modify_time': 1432392499.0, 'sub_caption': u'second', 'comment_count': 0, u'id': 32}]
默认情况下, 序列器会返回一个 list 或者 dict(对于单个 model 实例), 你可以设置参数 “ output_type ” 来决定序列器返回 json/raw.
##API 手册
####dss.Serializer 提供序列器
function serializer(data, datetime_format='timestamp', output_type='raw', include_attr=None, except_attr=None, foreign=False, many=False)
####Parameters:
####用法:
datetime_format:
|parameters|intro| | -------------- | :---: | |string|转换 datetime 为字符串。如: "2015-05-10 10:19:22"| |timestamp|转换 datetime 为时间戳。如: "1432124420.0"|
例子:
from dss.Serializer import serializer
article_list = Article.objects.all()
data = serializer(article_list, datetime_format='string', output_type='json')
data:
[
{
"read_count": 0,
"sub_caption": "first",
"publish": true,
"content": "first article",
"caption": "first",
"comment_count": 0,
"create_time": "2015-05-23 22:47:36",
"modify_time": "2015-05-23 22:47:36",
"id": 31
},
{
"read_count": 0,
"sub_caption": "second",
"publish": false,
"content": "second article",
"caption": "second",
"comment_count": 0,
"create_time": "2015-05-23 22:48:19",
"modify_time": "2015-05-23 22:48:19",
"id": 32
}
]
output_type
|parameters|intro|
| -------------- | :---: |
|raw|将 list 或 dict 中的特殊对象序列化后输出为 list 或 dict|
|dict|同 raw|
|json|转换数据为 json|
~~xml 转换数据为 xml~~ (暂时去除)
例子:
from dss.Serializer import serializer
article_list = Article.objects.all()[0]
data = serializer(article_list, output_type='json')
data:
{
"read_count": 0,
"sub_caption": "first",
"publish": true,
"content": "first article",
"caption": "first",
"comment_count": 0,
"create_time": "2015-05-23 22:47:36",
"modify_time": "2015-05-23 22:47:36",
"id": 31
}
include_attr
例子:
from dss.Serializer import serializer
article_list = Article.objects.all()
data = serializer(article_list, output_type='json', include_attr=('content', 'caption',))
data:
[
{
"content": "first article",
"caption": "first"
},
{
"content": "second article",
"caption": "second"
}
]
exclude_attr
例子:
from dss.Serializer import serializer
article_list = Article.objects.all()
data = serializer(article_list, output_type='json', except_attr=('content',))
data:
[
{
"read_count": 0,
"sub_caption": "first",
"publish": true,
"caption": "first",
"comment_count": 0,
"create_time": 1432392456,
"modify_time": 1432392456,
"id": 31
},
{
"read_count": 0,
"sub_caption": "second",
"publish": false,
"caption": "second",
"comment_count": 0,
"create_time": 1432392499,
"modify_time": 1432392499,
"id": 32
}
]
foreign
序列化数据中的 ForeignKeyField 及其子项目
例子:
from dss.Serializer import serializer
article_list = Article.objects.all()
data = serializer(article_list, output_type='json', include_attr=('classification', 'caption', 'create_time', foreign=True)
data:
[
{
"caption": "first",
"create_time": 1432392456,
"classification": {
"create_time": 1429708506,
"c_name": "python",
"id": 1,
"modify_time": 1429708506
}
},
{
"caption": "second",
"create_time": 1432392499,
"classification": {
"create_time": 1430045890,
"c_name": "test",
"id": 5,
"modify_time": 1430045890
}
}
]
many 序列化 ManyToManyField
example:
from dss.Serializer import serializer
article_list = Article.objects.all()
data = serializer(article_list, output_type='json', include_attr=('classification', 'caption', 'create_time', many=True)
测试数据无 ManyToManyField ,数据格式同上
####dss.Mixin 提供序列器 Mixin
class JsonResponseMixin(object)
datetime_type = 'string' # 输出 datetime 时间格式。默认为“ string ”,可选参数相见 dss.Serializer.serializer
foreign = False # 是否序列化 ForeignField 。默认为 False
many = False # 是否序列化 ManyToManyField 。默认为 False
include_attr = None # 只序列化 include_attr 包含的属性。默认为 None,接受一个包含属性名称的 tuple
exclude_attr = None # 不序列化 exclude_attr 包含的属性。默认为 None,接受一个包含属性名称的 tuple
####说明:
将普通 class based view 转换为返回 json 数据的 class based view ,适用于 DetailView 等
####用法:
例子:
# view.py
from dss.Mixin import JsonResponseMixin
from django.views.generic import DetailView
from model import Article
class TestView(JsonResponseMixin, DetailView):
model = Article
datetime_type = 'string'
pk_url_kwarg = 'id'
# urls.py
from view import TestView
urlpatterns = patterns('',
url(r'^test/(?P<id>(\d)+)/$', TestView.as_view()),
)
访问:localhost:8000/test/1/
response:
{
"article": {
"classification_id": 5,
"read_count": 0,
"sub_caption": "second",
"comments": [],
"content": "asdfasdfasdf",
"caption": "second",
"comment_count": 0,
"id": 32,
"publish": false
},
"object": {
"classification_id": 5,
"read_count": 0,
"sub_caption": "second",
"comments": [],
"content": "asdfasdfasdf",
"caption": "second",
"comment_count": 0,
"id": 32,
"publish": false
},
"view": ""
}
class MultipleJsonResponseMixin(JsonResponseMixin):
####说明:
将列表类视图转换为返回 json 数据的类视图,适用于 ListView 等
####用法:
例子:
# view.py
from dss.Mixin import MultipleJsonResponseMixin
from django.views.generic import ListView
from model import Article
class TestView(MultipleJsonResponseMixin, ListView):
model = Article
query_set = Article.objects.all()
paginate_by = 1
datetime_type = 'string'
# urls.py
from view import TestView
urlpatterns = patterns('',
url(r'^test/$', TestView.as_view()),
)
访问:localhost:8000/test/
response:
{
"paginator": "",
"article_list": [
{
"classification_id": 1,
"read_count": 2,
"sub_caption": "first",
"content": "first article",
"caption": "first",
"comment_count": 0,
"publish": false,
"id": 31
},
{
"classification_id": 5,
"read_count": 0,
"sub_caption": "",
"content": "testseteset",
"caption": "hehe",
"comment_count": 0,
"publish": false,
"id": 33
},
{
"classification_id": 5,
"read_count": 0,
"sub_caption": "second",
"content": "asdfasdfasdf",
"caption": "second",
"comment_count": 0,
"publish": false,
"id": 32
}
],
"object_list": [
{
"classification_id": 1,
"read_count": 2,
"sub_caption": "first",
"content": "first article",
"caption": "first",
"comment_count": 0,
"publish": false,
"id": 31
},
{
"classification_id": 5,
"read_count": 0,
"sub_caption": "",
"content": "testseteset",
"caption": "hehe",
"comment_count": 0,
"publish": false,
"id": 33
},
{
"classification_id": 5,
"read_count": 0,
"sub_caption": "second",
"content": "asdfasdfasdf",
"caption": "second",
"comment_count": 0,
"publish": false,
"id": 32
}
],
"page_obj": {
"current": 1,
"next": 2,
"total": 3,
"page_range": [
{
"page": 1
},
{
"page": 2
},
{
"page": 3
}
],
"previous": null
},
"is_paginated": true,
"view": ""
}
class FormJsonResponseMixin(JsonResponseMixin):
####说明:
将普通 class based view 转换为返回 json 数据的 class based view ,适用于 CreateView 、 UpdateView 、 FormView 等
####用法:
例子:
# view.py
from dss.Mixin import FormJsonResponseMixin
from django.views.generic import UpdateView
from model import Article
class TestView(FormJsonResponseMixin, UpdateView):
model = Article
datetime_type = 'string'
pk_url_kwarg = 'id'
# urls.py
from view import TestView
urlpatterns = patterns('',
url(r'^test/(?P<id>(\d)+)/$', TestView.as_view()),
)
访问:localhost:8000/test/1/
response:
{
"article": {
"classification_id": 5,
"read_count": 0,
"sub_caption": "second",
"content": "asdfasdfasdf",
"caption": "second",
"comment_count": 0,
"id": 32,
"publish": false
},
"form": [
{
"field": "caption"
},
{
"field": "sub_caption"
},
{
"field": "read_count"
},
{
"field": "comment_count"
},
{
"field": "classification"
},
{
"field": "content"
},
{
"field": "publish"
}
],
"object": {
"classification_id": 5,
"read_count": 0,
"sub_caption": "second",
"content": "asdfasdfasdf",
"caption": "second",
"comment_count": 0,
"id": 32,
"publish": false
},
"view": ""
}
####对额外数据的序列化支持:
当我们想在 model 中加入一些额外的数据并也想被序列化时, 现在可以这样做:
def add_extra(article):
comments = Comment.objects.filter(article=article)
setattr(article, 'comments', comments)
articles = Article.objects.all()
map(add_extra, articles)
result = serializer(articles)
序列化的结果数据中将会包含"comments"哦.
额外加入的数据可以是一个普通的数据类型、 另一个 Django model 、 字典、 列表甚至 QuerySet
django simple serializer 的实际例子: 个人网站后台数据接口
项目地址: django-simple-serializer
欢迎大家拍砖并提供宝贵意见。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.