django rest framework 入门1-序列化 Serialization

分类: Python 2013-01-22 22:24 11528人阅读 评论(0) 收藏 举报

************************************

广告时间:

海淘导航网站推荐:海淘库:http://www.haitaocool.com/

需要的请收藏哦

************************************

1. 设置一个新的环境

在我们开始之前, 我们首先使用virtualenv要创建一个新的虚拟环境,以使我们的配置和我们的其他项目配置彻底分开。

$mkdir ~/env

$virtualenv  ~/env/tutorial

$source ~/env/tutorial/bin/avtivate

现在我们处在一个虚拟的环境中,开始安装我们的依赖包

$pip install django

$pip install djangorestframework

$pip install pygments   ////使用这个包,做代码高亮显示

需要退出虚拟环境时,运行deactivate。更多信息,irtualenv document

2. 开始

环境准备好只好,我们开始创建我们的项目

$ cd ~

$ django-admin.py startproject tutorial

$ cd tutorial

项目创建好后,我们再创建一个简单的app

$python manage.py startapp snippets

我们使用sqlite3来运行我们的项目tutorial,编辑tutorial/settings.py, 将数据库的默认引擎engine改为sqlite3, 数据库的名字NAME改为tmp.db

  1. DATABASES = {
  2. 'default': {
  3. 'ENGINE': 'django.db.backends.sqlite3',
  4. 'NAME': 'tmp.db',
  5. 'USER': '',
  6. 'PASSWORD': '',
  7. 'HOST': '',
  8. 'PORT': '',
  9. }
  10. }

同时更改settings.py文件中的INSTALLD_APPS,添加我们的APP snippets和rest_framework

  1. INSTALLED_APPS = (
  2. ...
  3. 'rest_framework',
  4. 'snippets',
  5. )

在tutorial/urls.py中,将snippets app的url包含进来

  1. urlpatterns = patterns('',
  2. url(r'^', include('snippets.urls')),
  3. )

3. 创建Model

这里我们创建一个简单的nippets model,目的是用来存储代码片段。

  1. from django.db import models
  2. from pygments.lexers import get_all_lexers
  3. from pygments.styles import get_all_styles
  4. LEXERS = [item for item in get_all_lexers() if item[1]]
  5. LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
  6. STYLE_CHOICES = sorted((item, item) for item in get_all_styles())
  7. class Snippet(models.Model):
  8. created = models.DateTimeField(auto_now_add=True)
  9. title = models.CharField(max_length=100, default='')
  10. code = models.TextField()
  11. linenos = models.BooleanField(default=False)
  12. language = models.CharField(choices=LANGUAGE_CHOICES,
  13. default='python',
  14. max_length=100)
  15. style = models.CharField(choices=STYLE_CHOICES,
  16. default='friendly',
  17. max_length=100)
  18. class Meta:
  19. ordering = ('created',)

完成model时,记得sync下数据库

python manage.py syncdb

4. 创建序列化类

我们要使用我们的web api,要做的第一件事就是序列化和反序列化, 以便snippets实例能转换为可表述的内容,例如json.
我们声明一个可有效工作的串行器serializer。在snippets目录下面,该串行器与django
的表单形式很类似。创建一个serializers.py ,并将下面内容拷贝到文件中。

  1. from django.forms import widgets
  2. from rest_framework import serializers
  3. from snippets.models import Snippet
  4. class SnippetSerializer(serializers.Serializer):
  5. pk = serializers.Field() # Note: `Field` is an untyped read-only field.
  6. title = serializers.CharField(required=False,
  7. max_length=100)
  8. code = serializers.CharField(widget=widgets.Textarea,
  9. max_length=100000)
  10. linenos = serializers.BooleanField(required=False)
  11. language = serializers.ChoiceField(choices=models.LANGUAGE_CHOICES,
  12. default='python')
  13. style = serializers.ChoiceField(choices=models.STYLE_CHOICES,
  14. default='friendly')
  15. def restore_object(self, attrs, instance=None):
  16. """
  17. Create or update a new snippet instance.
  18. """
  19. if instance:
  20. # Update existing instance
  21. instance.title = attrs['title']
  22. instance.code = attrs['code']
  23. instance.linenos = attrs['linenos']
  24. instance.language = attrs['language']
  25. instance.style = attrs['style']
  26. return instance
  27. # Create new instance
  28. return Snippet(**attrs)

该序列化类的前面部分,定义了要序列化和反序列化的类型,restore_object 方法定义了如何通过反序列化数据,生成正确的对象实例。

我们也可以使用ModelSerializer来快速生成,后面我们将节省如何使用它。

5. 使用 Serializers

在我们使用我们定义的SnippetsSerializers之前,我们先熟悉下Snippets.

$python manage.py shell

进入shell终端后,输入以下代码:

  1. from snippets.models import Snippet
  2. from snippets.serializers import SnippetSerializer
  3. from rest_framework.renderers import JSONRenderer
  4. from rest_framework.parsers import JSONParser
  5. snippet = Snippet(code='print "hello, world"\n')
  6. snippet.save()

我们现在获得了一个Snippets的实例,现在我们对他进行以下序列化

  1. serializer = SnippetSerializer(snippet)
  2. serializer.data
  3. # {'pk': 1, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}

这时,我们将该实例转成了python原生的数据类型。下面我们将该数据转换成json格式,以完成序列化:

  1. content = JSONRenderer().render(serializer.data)
  2. content
  3. # '{"pk": 1, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}'

反序列化也很简单,首先我们要将一个输入流(content),转换成python的原生数据类型

  1. import StringIO
  2. stream = StringIO.StringIO(content)
  3. data = JSONParser().parse(stream)

然后我们将该原生数据类型,转换成对象实例

  1. serializer = SnippetSerializer(data=data)
  2. serializer.is_valid()
  3. # True
  4. serializer.object
  5. # <Snippet: Snippet object>

注意这些API和django表单的相似处。这些相似点, 在我们讲述在view中使用serializers时将更加明显。

6. 使用 ModelSerializers

SnippetSerializer使用了许多和Snippet中相同的代码。如果我们能把这部分代码去掉,看上去将更佳简洁。

类似与django提供Form类和ModelForm类,Rest Framework也包含了Serializer 类和 ModelSerializer类。

打开snippets/serializers.py ,修改SnippetSerializer类:

  1. class SnippetSerializer(serializers.ModelSerializer):
  2. class Meta:
  3. model = Snippet
  4. fields = ('id', 'title', 'code', 'linenos', 'language', 'style')

7. 通过Serializer编写Django View

让我们来看一下,如何通过我们创建的serializer类编写django view。这里我们不使用rest framework的其他特性,仅编写正常的django view。

我们创建一个HttpResponse 子类,这样我们可以将我们返回的任何数据转换成json。

在snippet/views.py中添加以下内容:

  1. from django.http import HttpResponse
  2. from django.views.decorators.csrf import csrf_exempt
  3. from rest_framework.renderers import JSONRenderer
  4. from rest_framework.parsers import JSONParser
  5. from snippets.models import Snippet
  6. from snippets.serializers import SnippetSerializer
  7. class JSONResponse(HttpResponse):
  8. """
  9. An HttpResponse that renders it's content into JSON.
  10. """
  11. def __init__(self, data, **kwargs):
  12. content = JSONRenderer().render(data)
  13. kwargs['content_type'] = 'application/json'
  14. super(JSONResponse, self).__init__(content, **kwargs)

我们API的目的是,可以通过view来列举全部的Snippet的内容,或者创建一个新的snippet

  1. @csrf_exempt
  2. def snippet_list(request):
  3. """
  4. List all code snippets, or create a new snippet.
  5. """
  6. if request.method == 'GET':
  7. snippets = Snippet.objects.all()
  8. serializer = SnippetSerializer(snippets)
  9. return JSONResponse(serializer.data)
  10. elif request.method == 'POST':
  11. data = JSONParser().parse(request)
  12. serializer = SnippetSerializer(data=data)
  13. if serializer.is_valid():
  14. serializer.save()
  15. return JSONResponse(serializer.data, status=201)
  16. else:
  17. return JSONResponse(serializer.errors, status=400)

注意,因为我们要通过client向该view post一个请求,所以我们要将该view 标注为csrf_exempt, 以说明不是一个CSRF事件。

Note that because we want to be able to POST to this view from clients that won't have a CSRF token we need to mark the view as csrf_exempt. This isn't something that you'd normally want to do, and REST framework views actually use more sensible behavior than this, but it'll do for our purposes right now.

我们也需要一个view来操作一个单独的Snippet,以便能更新/删除该对象。

  1. @csrf_exempt
  2. def snippet_detail(request, pk):
  3. """
  4. Retrieve, update or delete a code snippet.
  5. """
  6. try:
  7. snippet = Snippet.objects.get(pk=pk)
  8. except Snippet.DoesNotExist:
  9. return HttpResponse(status=404)
  10. if request.method == 'GET':
  11. serializer = SnippetSerializer(snippet)
  12. return JSONResponse(serializer.data)
  13. elif request.method == 'PUT':
  14. data = JSONParser().parse(request)
  15. serializer = SnippetSerializer(snippet, data=data)
  16. if serializer.is_valid():
  17. serializer.save()
  18. return JSONResponse(serializer.data)
  19. else:
  20. return JSONResponse(serializer.errors, status=400)
  21. elif request.method == 'DELETE':
  22. snippet.delete()
  23. return HttpResponse(status=204)

将views.py保存,在Snippets目录下面创建urls.py,添加以下内容:

  1. urlpatterns = patterns('snippets.views',
  2. url(r'^snippets/$', 'snippet_list'),
  3. url(r'^snippets/(?P<pk>[0-9]+)/$', 'snippet_detail'),
  4. )

注意我们有些边缘事件没有处理,服务器可能会抛出500异常。

8. 测试

现在我们启动server来测试我们的Snippet。

在python mange.py shell终端下执行(如果前面进入还没有退出)

>>quit()

执行下面的命令, 运行我们的server:

  1. python manage.py runserver
  2. Validating models...
  3. 0 errors found
  4. Django version 1.4.3, using settings 'tutorial.settings'
  5. Development server is running at http://127.0.0.1:8000/
  6. Quit the server with CONTROL-C.

新开一个terminal来测试我们的server

序列化:

  1. url http://127.0.0.1:8000/snippets/
  2. [{"id": 1, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"}]
  1. url http://127.0.0.1:8000/snippets/1/
  2. {"id": 1, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "sty

django rest framework 入门的更多相关文章

  1. Django REST framework入门 (转自中文文档)

    快速入门 我们将创建一个简单的允许管理员用户查看和编辑系统中的用户和组的API. 项目设置 创建一个名为 tutorial 的新django项目,然后启动一个名为 quickstart 的新app. ...

  2. 121、Django rest framework入门使用

    框架介绍 为你的django平台通过model生成对应的restfull api,并可以通过对应的http接口来进行 post .get.put.delete等操作.本文是也并非入门级别,不会带你去了 ...

  3. Django REST framework快速入门指南

    项目设置 创建一个名为tutorial的新Django项目,然后开始一个名为quickstart的新应用程序. # Create the project directory mkdir tutoria ...

  4. Django REST Framework简单入门(一)

    Django REST Framework(简称DRF),是一个用于构建Web API的强大且灵活的工具包. REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的. ...

  5. Django REST framework快速入门(官方文档翻译翻译)

    开始 我们将创建一个简单的API来允许管理员用户查看和编辑系统中的用户和组. 项目设置 创建一个新的django项目,命名为:<tutorial>,然后创建一个新的应用程序(app),命名 ...

  6. Django REST framework完全入门

    Django REST framework 一个强大灵活的Django工具包,提供了便捷的 REST API 开发框架 我们用传统的django也可以实现REST风格的api,但是顶不住Django ...

  7. 用Django Rest Framework和AngularJS开始你的项目

    Reference: http://blog.csdn.net/seele52/article/details/14105445 译序:虽然本文号称是"hello world式的教程&quo ...

  8. Django REST framework 中文教程1:序列化

    建立环境 在我们做任何事情之前,我们将使用virtualenv创建一个新的虚拟环境.这将确保我们的包配置与我们正在开展的任何其他项目保持良好的隔离. virtualenv envsource env/ ...

  9. Python Django rest framework

    本节内容 Django rest framework 安装 Django rest framwwork 环境配置 简单举例说明 Django中使用 rest framework 1.1 安装 Djan ...

随机推荐

  1. [BZOJ1263][SCOI2006]整数划分(数学+高精度)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1263 分析:数学老师上课讲过啦= =,就是尽可能3越多越好.然后就写个高精度就行了.

  2. 自然数从1到n之间,有多少个数字含有1

        问题明确而简单.for循环肯定是不好的.       用递推方法:       定义h(n)=从1到9999.....9999  ( n 个 9)之间含有1的数字的个数.定义f(n)为n位数中 ...

  3. 曾经post为何只能通过form来提交

    当我们web程序的前台,需要有数据向后台发送时候,我们第一时间想到的就是,给我们所需要提交的用户名,密码之类的数据封装到一个<form>表单里面去,而封装完毕之后,我们需要给form的提交 ...

  4. iOS -- 上传多张图片 后台(PHP)代码和上传一张的一样

    // 上传多张图片 - (void)send { // 设置初始记录量为0 self.count = 0; self.upcount = 0; // 设置初始值为NO self.isUploadPic ...

  5. webpack入坑之旅(六)配合vue-router实现SPA

    这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...

  6. 屠龙之路_狭路相逢勇者胜_EighthDay

    屠龙天团的少年们追着Alpha恶龙沿路留下的粪便,一路狂奔追到了福州大学生活区三十号楼4层活动室,空气中弥漫着恶龙的臭味!屠龙少年对恶龙的隐身遁迹之术心知肚明,于是点头示意,四下散开.各自拿出了电脑, ...

  7. Beta版本冲刺Day2

    会议讨论 628:       和建平同学一起合作解决了如何获取勾选事件,将勾选的课程信息存入select表格中.但是当运行更新后的项目遇到了无法连接数据库的问题了,目前还在解决中. 因为碰到了这样的 ...

  8. VS2015中GLAUX库的链接问题

    最近学习OpenGL,照着例子写了个程序,用到了GLAUX库. #include <gl\glaux.h> #pragma comment(lib, "glaux") ...

  9. confluence的安装、备份和恢复(wiki)

    还有一种比较不错的wiki工具MediaWiki 安装教程参考 http://pangge.blog.51cto.com/6013757/1560249 我是按照上面的教程搭建的 还有几篇不错的文章 ...

  10. 重新打开singleTask画面时传值问题

    记录学习之用 大家都知道假如当我们的A画面设置了android:launchMode="singleTask"时,从A画面跳到B画面之前没有finishA画面,然后在B画面使用st ...