Django轻松构建RESTful接口

时间:2009-11-13 23:03:56

标签: python django rest

我正在寻找借口来学习Django的新项目。通常,我喜欢构建RESTful服务器端接口,其中URL映射到在某些独立于平台的上下文(例如XML或JSON)中吐出数据的资源。这是 在没有使用框架的情况下可以做得相当简单,但是其中一些如Ruby on Rails可以根据您现有的模型代码,根据您传递的URL类型轻松地将XML反射回客户端。

我的问题是,像Django这样的东西是否支持这个?我用Google搜索并发现了一些可以放在Django之上的“RESTful”第三方代码。不确定我是否太热衷于此。

如果不是Django,任何其他已经构建的Python框架都考虑到了这一点,所以我不必重新发明轮子,因为我已经有像PHP这样的语言了?

6 个答案:

答案 0 :(得分:15)

这可能很容易做到。

URL映射很容易构建,例如:

urlpatterns = patterns('books.views',
  (r'^books/$', 'index'),
  (r'^books/(\d+)/$', 'get'))

Django支持model serialization,因此很容易将模型转换为XML:

from django.core import serializers
from models import Book

data = serializers.serialize("xml", Book.objects.all())

将两者与decorators结合使用,您可以构建快速,快速的处理程序:

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)

答案 1 :(得分:4)

(我必须编辑最明显的链接。)

+1 piston - (上面的链接)。我过去曾使用apibuilder(华盛顿时报开源),但Piston对我来说更容易。对我来说最困难的是找出API的URL结构,并帮助处理正则表达式。我还使用了surlex,这使得这件苦差事更容易。

示例,将此模型用于Group(来自我们正在制定的时间表系统):

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

这个urls.py片段(请注意,surlex允许轻松设置正则表达式宏):

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),)

然后这个处理程序将监视JSON输出(默认情况下),也可以执行XML和YAML

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()

正如您所看到的,大多数处理程序代码都在确定urlpatterns中传递的参数。

一些示例网址是api/groups/api/group/3301/api/group/st1gp01/ - 所有这些网址都会输出JSON

答案 2 :(得分:3)

看一下Piston,它是Django创建RESTful API的迷你框架。

Eric Holscher最近的博客文章提供了有关使用活塞的PRO的更多见解:Large Problems in Django, Mostly Solved: APIs

答案 3 :(得分:2)

它可以响应任何类型的数据。 JSON / XML / PDF / pictures / CSV ......

Django本身带有set of serializers

修改

我刚看了Piston - 看起来很有希望。最佳功能:

  

坚持你的方式。

:)

答案 4 :(得分:2)

关于不喜欢第三方代码的评论 - 这太糟糕了,因为可插拔应用程序是django最强大的功能之一。像其他人一样回答,活塞将为你完成大部分工作。

答案 5 :(得分:1)

一年多前,我在Django为一家大型西雅图公司写了一个REST网络服务,该公司在互联网上播放流媒体。

Django非常出色。观察到“付费的书呆子”,Django URL配置非常棒:您可以按照自己喜欢的方式设置URL,并让它提供适当的对象。

我不喜欢的一件事:Django ORM绝对不支持二进制BLOB。如果要提供照片或其他内容,则需要将它们保存在文件系统中,而不是数据库中。因为我们使用多个服务器,所以我必须在编写自己的BLOB支持或找到一些复制框架之间做出选择,该框架将使所有服务器保持最新的二进制数据。 (我选择写自己的BLOB支持。这不是很难,所以我真的很生气,Django的人没有做那项工作。应该有一个,最好只有一个,显而易见的做法。)

我非常喜欢Django ORM。它使数据库部分非常简单;您不需要知道任何 SQL。 (我不喜欢SQL而且我喜欢Python,所以这是一个双赢。)免费获得的“管理界面”为您提供了一种查看数据并在测试期间戳入数据的好方法和发展。

我毫无保留地推荐Django。