Django простота создания интерфейса RESTful - PullRequest
10 голосов
/ 14 ноября 2009

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

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

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

Ответы [ 6 ]

15 голосов
/ 14 ноября 2009

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

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)
4 голосов
/ 16 ноября 2009

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

+ 1 для piston - (ссылка выше). Раньше я использовал apibuilder (с открытым исходным кодом Washington Times), но Поршень мне проще. Самое сложное для меня - выяснить структуру 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 .

3 голосов
/ 15 ноября 2009

Взгляните на Piston, это мини-фреймворк для Django для создания RESTful API.

Недавнее сообщение в блоге Эрика Холшера (Eric Holscher) дает более подробное представление о плюсах использования Piston: Большие проблемы в Django, в основном решены: API

2 голосов
/ 24 ноября 2009

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

2 голосов
/ 14 ноября 2009

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

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

Редактировать

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

Держится подальше.

:)

1 голос
/ 14 ноября 2009

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...