Простота создания Django интерфейса RESTful

Я ищу оправдание, чтобы изучить Django для нового проекта, который появился. Обычно мне нравится создавать RESTful серверные интерфейсы, где URL-адрес сопоставляется с ресурсами, которые выплескивают данные в определенном независимом от платформы контексте, таком как XML или JSON. Это довольно просто обойтись без использования фреймворков, но некоторые из них, такие как Ruby on Rails, позволяют вам легко переплевывать XML-клиент на основе типа URL-адреса, который вы передаете, на основе существующего кода модели.

Мой вопрос: у чего-то вроде Django есть поддержка? Я googled и нашел некоторый "RESTful" сторонний код, который может идти поверх Django. Не уверен, что я слишком увлечен этим.

Если не Django, любая другая инфраструктура Python, которая уже построена с учетом этого, поэтому мне не нужно изобретать колесо, как я уже имею в таких языках, как PHP?

Ответ 1

Это, вероятно, довольно легко сделать.

Отображение 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)

Ответ 2

(мне пришлось отредактировать наиболее очевидные ссылки.)

+1 для piston - (ссылка выше). В прошлом я использовал apibuilder (Washington Times open source), но Piston работает для меня легче. Самое сложное для меня - выяснить структуры URL для API и помочь с регулярными выражениями. Я также использовал 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.

Некоторые примеры URL-адресов api/groups/, api/group/3301/ и api/group/st1gp01/ - все из которых будут выводиться JSON.

Ответ 4

Он может отвечать любыми данными. JSON/XML/PDF/images/CSV...

Сам Django поставляется с набором сериализаторов.

Edit

Я просто посмотрел на Piston - выглядит многообещающим. Лучшая функция:

Остается на вашем пути.

:)

Ответ 5

Относительно вашего комментария о том, что вы не любите сторонний код - это слишком плохо, потому что приложения с подключаемыми приложениями являются одним из лучших функций django. Как и другие, поршень будет выполнять большую часть работы за вас.

Ответ 6

Немногим более года назад я написал веб-службу REST в Django для большой компании в Сиэтле, которая делает потоковые медиа в Интернете.

Django отлично подходит для этой цели. Как заметил "платный ботаник", конфигурация URL-адреса Django замечательна: вы можете настроить свои URL-адреса именно так, как вы хотите, и заставить их обслуживать соответствующие объекты.

Единственное, что мне не понравилось: Django ORM абсолютно не поддерживает двоичные BLOB. Если вы хотите подавать фотографии или что-то еще, вам необходимо сохранить их в файловой системе, а не в базе данных. Поскольку мы использовали несколько серверов, мне приходилось выбирать между написанием моей собственной поддержки BLOB или обнаружением некоторой структуры репликации, которая обеспечивала бы обновление всех серверов последними двоичными данными. (Я решил написать свою собственную поддержку BLOB. Это было не очень сложно, поэтому мне было очень досадно, что ребята из Django не выполняли эту работу. Должен быть один, и желательно только один, очевидный способ сделать что-то.)

Мне очень нравится Django ORM. Это делает часть базы данных очень простой; вам не нужно знать SQL. (Мне не нравится SQL, и мне нравится Python, так что это двойная победа.) "Интерфейс администратора", который вы получаете бесплатно, дает вам отличный способ просматривать ваши данные и подталкивать данные во время тестирования и развитие.

Я рекомендую Django без оговорок.