写后台的时候经常需要写数据接口,这时就需要用到序列化工具, 而默认到序列化工具对 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
欢迎大家拍砖并提供宝贵意见。
文中这里格式乱了,重发一下:
为什么要用 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 。
1
felixzhu 2016-06-15 11:58:45 +08:00
这个和 django-rest-framework 提供的 serializer 之类的有什么区别啊
|
2
rapospectre OP @felixzhu 序列化的结果是一样的,但是我写的这个使用非常简单, 直接用就可以。 django-rest-framework 和它相比的弊端我在文中提到了。当然已经使用 drf 并且非常顺手也可以看看我这个呀,吐吐槽,看看哪里做的不好 0.0
|
3
brucedone 2016-06-15 12:54:08 +08:00
why not flask ?
|
4
rapospectre OP @brucedone 这就是给 Django 的一个解决方案,当然用 flask 做 API 服务也可以,@-@
|
5
daimoon 2016-06-16 08:13:33 +08:00
不过我还是觉的有必要花时间学习下 restframework 。学习成本略高,确实非常方便。
|
6
rapospectre OP @daimoon 是的,不过你可以拿出学 drf 百分之一的时间试试这个呀,也很方便哒。
|
7
nimdanoob 2016-06-16 15:41:48 +08:00
good work
|
8
rapospectre OP @nimdanoob 谢谢!
|
9
KgM4gLtF0shViDH3 2017-05-21 18:50:03 +08:00
看 GitHub 上已经支持 python3 了,作者好勤快呀,支持一个。
|
10
rapospectre OP @bestkayle 谢谢支持!
|
11
KgM4gLtF0shViDH3 2017-05-22 18:54:03 +08:00
@rapospectre #10 还需要头条大神的指教呢-0-
|