Python Django易于构建RESTful接口
我正在为一个新项目寻找学习Django的借口。通常,我喜欢构建RESTful服务器端接口,其中URL映射到在一些独立于平台的上下文(如XML或JSON)中吐出数据的资源。这是 不使用框架非常简单,但其中一些框架(如RubyonRails)可以方便地让您根据传递给客户机的URL类型,基于现有的模型代码,轻松地向客户机回吐XML 我的问题是,像Django这样的东西是否支持这一点?我在谷歌上找到了一些可以放在Django之上的“RESTful”第三方代码。我不知道我是否太喜欢这个Python Django易于构建RESTful接口,python,django,rest,Python,Django,Rest,我正在为一个新项目寻找学习Django的借口。通常,我喜欢构建RESTful服务器端接口,其中URL映射到在一些独立于平台的上下文(如XML或JSON)中吐出数据的资源。这是 不使用框架非常简单,但其中一些框架(如RubyonRails)可以方便地让您根据传递给客户机的URL类型,基于现有的模型代码,轻松地向客户机回吐XML 我的问题是,像Django这样的东西是否支持这一点?我在谷歌上找到了一些可以放在Django之上的“RESTful”第三方代码。我不知道我是否太喜欢这个 如果不是Djang
如果不是Django,任何其他Python框架都已经考虑到了这一点,因此我不必像在PHP等语言中那样重新发明轮子?它可以响应任何类型的数据。JSON/XML/PDF/pictures/CSV Django本身就有一个 编辑 我只是看了一眼——看起来很有希望。最佳功能: 别挡你的路
:)这可能很容易做到 URL映射易于构造,例如:
urlpatterns = patterns('books.views',
(r'^books/$', 'index'),
(r'^books/(\d+)/$', 'get'))
Django支持,因此很容易将模型转换为XML:
from django.core import serializers
from models import Book
data = serializers.serialize("xml", Book.objects.all())
将两者结合使用,您可以构建快速、快速的处理程序:
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
def xml_view(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return HttpResponse(serializers.serialize("xml", result),
mimetype="text/xml")
return wrapper
@xml_view
def index(request):
return Books.objects.all()
@xml_view
def get(request, id):
return get_object_or_404(Book, pk=id)
一年多前,我在Django为西雅图一家在互联网上提供流媒体服务的大型公司编写了一个REST web服务 Django在这方面非常出色。正如“付费书呆子”所观察到的,Django URL配置非常棒:你可以按照你想要的方式设置你的URL,并让它提供适当的对象 有一件事我不喜欢:Django ORM绝对不支持二进制blob。如果你想提供照片或其他东西,你需要将它们保存在文件系统中,而不是数据库中。因为我们使用了多台服务器,所以我必须在编写自己的BLOB支持或找到某种复制框架之间做出选择,以使所有服务器都能使用最新的二进制数据保持最新。(我选择编写自己的BLOB支持。这并不难,所以我对Django的人没有做这项工作感到恼火。应该有一种,最好只有一种明显的方法来做某事。) 我真的很喜欢Django ORM。它使数据库部分变得非常简单;您不需要知道任何SQL。(我不喜欢SQL,我喜欢Python,所以这是双赢的。)“管理界面”是免费提供的,它为您提供了一种查看数据的好方法,并在测试和开发期间插入数据
我毫无保留地推荐Django。看看活塞,它是Django创建RESTful API的一个小框架 Eric Holscher最近的一篇博客文章提供了更多关于使用活塞的好处的见解:(我不得不编辑掉最明显的链接。) +1用于
活塞
-(上面的链接)。我过去使用过apibuilder(华盛顿时报开源),但对我来说工作起来更容易。对我来说,最困难的事情是找出API的URL结构,并帮助使用正则表达式。我还使用了一种新的方法,这使得做家务容易多了
例如,将此模型用于组(来自我们正在研究的时间表系统):
正如您所看到的,大多数处理程序代码都是在计算在urlpatterns
中传递的参数
一些示例URL是api/groups/
、api/group/3301/
和api/group/st1gp01/
——所有这些都将输出。关于您不喜欢第三方代码的评论,这太糟糕了,因为可插拔应用程序是django最伟大的功能之一。和其他人回答的一样,活塞将为您完成大部分工作 django活塞正常。在我看来,它仍然有点不成熟。创建一个类似的json_视图
装饰器:返回HttpResponse(json.dumps(result),mimetype=“application/json”)
(可以安装simplejson
,也可以使用Python 2.6及更高版本中的内置json
模块。)或者,如果我们已经在使用序列化程序,您可以使用返回HttpResponse(serializers.serialize('json',result),mimetype=“application/json”)
class Group(models.Model):
"""
Tree-like structure that holds groups that may have other groups as leaves.
For example ``st01gp01`` is part of ``stage1``.
This allows subgroups to work. The name is ``parents``, i.e.::
>>> stage1group01 = Group.objects.get(unique_name = 'St 1 Gp01')
>>> stage1group01
>>> <Group: St 1 Gp01>
# get the parents...
>>> stage1group01.parents.all()
>>> [<Group: Stage 1>]
``symmetrical`` on ``subgroup`` is needed to allow the 'parents' attribute to be 'visible'.
"""
subgroup = models.ManyToManyField("Group", related_name = "parents", symmetrical= False, blank=True)
unique_name = models.CharField(max_length=255)
name = models.CharField(max_length=255)
academic_year = models.CharField(max_length=255)
dept_id = models.CharField(max_length=255)
class Meta:
db_table = u'timetable_group'
def __unicode__(self):
return "%s" % self.name
from surlex.dj import surl
from surlex import register_macro
from piston.resource import Resource
from api.handlers import GroupHandler
group_handler = Resource(GroupHandler)
# add another macro to our 'surl' function
# this picks up our module definitions
register_macro('t', r'[\w\W ,-]+')
urlpatterns = patterns('',
# group handler
# all groups
url(r'^groups/$', group_handler),
surl(r'^group/<id:#>/$', group_handler),
surl(r'^group/<name:t>/$', group_handler),)
class GroupHandler(BaseHandler):
"""
Entry point for Group model
"""
allowed_methods = ('GET', )
model = Group
fields = ('id', 'unique_name', 'name', 'dept_id', 'academic_year', 'subgroup')
def read(self, request, id=None, name=None):
base = Group.objects
if id:
print self.__class__, 'ID'
try:
return base.get(id=id)
except ObjectDoesNotExist:
return rc.NOT_FOUND
except MultipleObjectsReturned: # Should never happen, since we're using a primary key.
return rc.BAD_REQUEST
else:
if name:
print self.__class__, 'Name'
return base.filter(unique_name = name).all()
else:
print self.__class__, 'NO ID'
return base.all()