Russian (Pусский) translation by Liliya (you can also view the original English article)
Итак, вы учитесь использовать Django Web Framework и вы любите его. Но вам нужен привлекательный, простой в использовании API для вашего приложения? Посмотрите не дальше, чем Django Rest Framework (DRF). DRF является мощным, утонченный и удивительно простым в использовании. Он предлагает привлекательную, доступную в Интернете версию вашего API и возможность возврата сырого JSON. Django Rest Framework обеспечивает мощную сериализацию модели, отображение данных с использованием стандартных представлений, основанных на функциях, или получить гранулы с мощными представлениями на основе классов для более сложных функций. Все в полностью совместимой REST оболочке. Давайте начнем.
Укладка фундамента
При работе с приложениями Python всегда рекомендуется изолировать вашу разработку виртуальной средой. Это помогает предотвратить конфликты версий между библиотеками, которые вам нужны в вашем приложении, и библиотеки, которые вы, возможно, уже установили на вашем компьютере, упрощают установку зависимостей в виртуальном env с помощью файла requirements.txt
, и, наконец, он обеспечивает совместное использование среды разработки с помощью других разработчиков.
Tuts + имеет два отличных видео о том, как установить virtualenv и virtualenvwrapper. Потратьте несколько минут, чтобы пройти через эти видеоролики, чтобы получить virtualenv и virtualenvwrapper, установленные на вашем компьютере. Если вы уже установили их, пропустите следующий раздел.
Настройка виртуальной среды
Первое, что мы сделаем как часть нашего приложения, - это настроить виртуальную среду. Введите в свой терминал следующие команды.
$ mkvirtualenv drf $ workon drf
Неважно, где вы находитесь в файловой системе, когда эти команды запущены. Все файлы virtualenv хранятся в централизованном месте и активируются по требованию.
Установка приложения Django
Поскольку в этой статье речь не идет о самом Django, я сэкономил некоторое время, создав репозиторий, содержащий приложение, в котором мы будем работать. Это простая книжная полка, которая позволит нам хранить списки авторов и книг. Загрузите репозиторий компаньонов в эту статью в каталог по вашему выбору, а затем запустите pip install -r requirements.txt
, чтобы установить все зависимости. Не забудьте убедиться, что вы активировали виртуальную среду, которую мы установили на последнем шаге. По завершении установки вы можете ввести fab runningerver
для запуска локального веб-сервера и открыть веб-браузер, указывающий на http://127.0.0.1:8000/
. Если вы видите список авторов на экране, тогда вам будет хорошо дальше двигаться.
Если в какой-то момент вы не получите ожидаемых результатов, попробуйте переключить ветвь локального репозитория в финал, чтобы увидеть результаты: git checkout final
.
Fab? Что это?
Fab == Fabric, бегун для задач Python. Из документов:
«Fabric - это библиотека Python (2,5 или выше) и средство командной строки для оптимизации использования SSH для задач развертывания приложений или системного администрирования».
Хотя более полная дискуссия о Fabric выходит за рамки этой статьи, я внедрил некоторые основные команды fab, которые упрощают работу с этим приложением. Вы видели команду fab runserver
. Существует также команда fab shell
, которая вызывает интерактивную оболочку iPython в контексте приложения и команду fab syncdb
, которая запускает команду syncdb
Django для синхронизации изменений в моделях с базой данных.
Работа с сериализацией
Одной из мощных возможностей Django Rest Framework является встроенная сериализация модели, которую она предлагает. Имея всего несколько строк кода, вы можете создавать мощные представления ваших данных, которые могут быть доставлены в нескольких форматах. Как уже упоминалось ранее, наше приложение будет простым приложением хранения книг и авторов. Я уже создал для вас модели Author
and Book
, поэтому откройте /app/bookreview/models.py
. Уже есть несколько авторов, хранящихся в локальной базе данных SQLite, поэтому давайте откроем интерактивную оболочку для нашего приложения и поработаем. Перейдите в окно терминала, убедитесь, что вы находитесь в ./app
и введите следующую команду.
$ fab shell
После загрузки оболочки введите следующие несколько строк, чтобы получить запись автора из базы данных, которая просто оказалась моей. Какое совпадение. :)
$ from bookreview.models import Author $ author = Author.objects.get(pk=1) $ author.id > 1 $ author.first_name > u'Andy' $ author.last_name > u'Matthews'
Аналогичным образом вы можете получить все записи автора из базы данных с помощью другой команды:
$ from bookreview.models import Author $ authors = Author.objects.all() $ authors > [<Author: Andy Matthews>, <Author: China Mieville>, <Author: Neil Gaiman>, <Author: Veronica Roth>, <Author: Suzanne Collins>, <Author: Brandon Sanderson>, <Author: Rick Riordan>, <Author: Phillip K. Dick>, <Author: John Scalzi>, <Author: Jesse Petersen>]
К сожалению, это не возвращает данные, которые может понять вызов AJAX. Итак, добавим сериализатор для авторов. Закройте оболочку, набрав quit
и откройте bookreview / serializers.py
. Введите или вставьте следующие несколько строк кода и сохраните файл.
class AuthorSerializer(serializers.ModelSerializer): """ Serializing all the Authors """ class Meta: model = Author fields = ('id', 'first_name', 'last_name')
Не внося никаких изменений, сериализатор дает нам довольно много мощи. Вернитесь в оболочку и давайте рассмотрим.
$ from bookreview.models import Author $ from bookreview.serializers import AuthorSerializer $ author = Author.objects.get(pk=1) $ serialized = AuthorSerializer(author) $ serialized.data > {'id': 1, 'first_name': u'Andy', 'last_name': u'Matthews'}
Давайте добавим еще несколько строк кода и посмотрим, что наш API покажет нам в браузере после того, как наши данные будут запущены через наш новый AuthorSerializer
.
Проверка API-интерфейса, доступного в Интернете
Сначала откройте bookreview / urls.py
и добавьте следующую строку сразу после маршрута index_view
:
url(r'^authors/$', views.AuthorView.as_view(), name='author-list'),
Затем откройте bookreview / views.py
и добавьте эти строки в конец файла:
class AuthorView(generics.ListAPIView): """ Returns a list of all authors. """ model = Author serializer_class = AuthorSerializer
Затем добавьте импорт для AuthorSerializer
в верхней части страницы:
from bookreview.serializers import AuthorSerializer
Представление по умолчанию для Django Rest Framework - это APIView. Он позволяет вам определять свои методы get
, put
и delete
. Это хороший способ получить базовую функциональность, но все же контролировать конечный результат. В нашем случае, однако, мы позволяем DRF делать тяжелый подъем для нас, расширяя ListAPIView. Нам просто нужно предоставить несколько бит информации, чтобы позволить DRF подключать куски. Мы даем ему модель автора
, чтобы он знал, как разговаривать с базой данных, и AuthorSerializer
, чтобы DRF знал, как вернуть информацию. Мы будем работать только с несколькими встроенными APIViews, но вы можете прочитать обо всех параметрах на веб-сайте Django Rest Framework.
Теперь, когда вы внесли эти изменения, убедитесь, что у вас запущен сервер, набрав fab runningerver
, введите URL http://127.0.0.1:8000/authors/
. Вы должны увидеть привлекательно разработанную страницу просмотра API, содержащую список всех авторов в базе данных.
Теперь, когда у нас есть представление API авторов, попробуйте нажать этот URL с помощью команды curl
:
$ curl http://127.0.0.1:8000/authors/ > [{"id": 1, "first_name": "Andy", "last_name": "Matthews"},..., {"id": 10, "first_name": "Jesse", "last_name": "Petersen"}]
Довольно шумный, да?
Предоставьте несколько авторских книг!
Хотя этот вид API довольно красивый, он один-к-одному с базой данных. Давайте перейдем к нашему представлению API, составив более сложный набор данных для авторов, включив список всех своих книг. Откройте bookreview / serializers.py
и добавьте следующую строку кода перед определением класса AuthorSerializer
.
class BookSerializer(serializers.ModelSerializer): """ Serializing all the Books """ class Meta: model = Book fields = ('id', 'title', 'isbn')
Прежде чем мы сможем добавить книги в AuthorSerializer
, мы должны сериализовать книги. Это должно быть полностью знакомо вам. Поскольку он почти идентичен AuthorSerializer
, мы не будем обсуждать его.
Затем добавьте следующую строку сразу после docstring класса AuthorSerializer
:
books = BookSerializer(many=True)
Затем добавьте книги
в свойство полей внутреннего класса Meta AuthorSerializer
:
fields = ('id', 'first_name', 'last_name', 'books')
Перезагрузите /authors/
в конечном результате, и теперь вы должны увидеть массив книг для каждого автора. Неплохо бы еще несколько строк кода, да?.
Хороший парень DRF!
Использование SerializerMethodField для создания пользовательских свойств
Сериализатор умный ... когда мы укажем, какую модель он должен сериализовать внутри внутреннего метакласса, он знает все об этой модели ... свойствах, длине, значениях по умолчанию и т. д. Обратите внимание, что мы не определяем какие-либо свойства, найденные в модели непосредственно в сериализаторе, мы укажем только, какие поля должны быть возвращены API в свойстве fields
.
Поскольку DRF уже знает о свойствах модели, это не требует от нас повторения. Если бы мы хотели, мы могли бы быть явными в BookSerializer
и добавлять следующие строки ... и DRF был бы так же счастлив.
title = serializers.Field(source='title') isbn = serializers.Field(source='isbn')
Метод serializers.field
позволяет указать на существующее свойство модели, исходное
поле и позволяет явно называть его чем-то другим при возврате его конечному пользователю. Но как насчет serializers.SerializerMethodField
? Это позволяет вам по существу создать настраиваемое свойство, которое напрямую не привязано к модели, содержимое которой является результатом вызова метода. В нашем случае мы вернем URL-адрес, который содержит список мест, куда вы могли бы пойти, чтобы купить книгу. Давайте добавим этот пользовательский метод.
Сразу после строки документации BookSerializer
добавьте следующую строку:
search_url = serializers.SerializerMethodField('get_search_url')
Затем после определения класса Meta
BookSerializer
добавьте следующие строки:
def get_search_url(self, obj): return "http://www.isbnsearch.org/isbn/{}".format(obj.isbn)
Затем, наконец, нам нужно добавить наше новое свойство в список полей. Измените это:
fields = ('id', 'title', 'isbn')
к этому:
fields = ('id', 'title', 'isbn', 'search_url')
Перезагрузите /authors/
в конечном результате, и теперь вы должны увидеть URL-адрес, возвращающийся вместе с другой информацией о книге.
Добавление конечной точки автора
У нас уже есть список авторов, но было бы хорошо, если бы у каждого автора была своя страница ... точно так же, как MySpace? Позволяет добавить конечную точку API для просмотра одного автора. Откройте urls.py
и добавьте следующую строку после маршрута author-list
:
url(r'^authors/(?P<pk>[\d]+)/$', views.AuthorInstanceView.as_view(), name='author-instance'),
Затем откройте view.py
и добавьте следующие строки после класса AuthorView
:
class AuthorInstanceView(generics.RetrieveAPIView): """ Returns a single author. Also allows updating and deleting """ model = Author serializer_class = AuthorSerializer
Нажмите одно из имен авторов на индексной странице, и вы увидите, что страница авторского экземпляра загружается.
Рефакторинг для победы!
Теперь самое подходящее время для быстрого рефакторинга. Поскольку Django предлагает вариант назначения ваших маршрутов, мы можем ссылаться на маршрут по этому имени. Это не позволяет нам создавать URL-адрес вручную. Откройте templates/index.html
и замените следующий фрагмент:
<a href="/authors/{{author.id}}/">{{author.first_name}} {{author.last_name}}</a>
с этой линией
<a href="{% url 'author-instance' author.id %}">{{author.first_name}} {{author.last_name}}</a>
Сохранение данных: пусть DRF работает для вас!
До сих пор наше приложение было только для чтения. Пора начать сохранять некоторые данные. Откройте templates/index.html
и добавьте следующие строки под заголовком авторов:
Введите имя, ваше, если хотите, и нажмите submit ... и скоро, вы получите ... ошибку?
DRF не совсем такой магический ... или не так ли?
Откройте views.py
, измените класс, который AuthorView
расширяет с generics.ListAPIView
на generics.ListCreateAPIView
. Затем повторите попытку. Бум! Вы автор! И ваш учитель гимнастики четвертого класса сказал, что вы ни на что не годитесь. Но что он знал, он работал каждый день вокруг потных носков. Вернитесь на главную страницу автора, чтобы увидеть свое имя в огнях.
Что сейчас произошло? По умолчанию API View, который мы использовали, разрешал только запросы GET
конечной точке авторов. Изменив его на ListCreateAPIView, мы сказали DRF, что хотим также разрешить POST
запросы. Он делает все остальное для нас. Мы могли бы также легко определить наш собственный метод post
в AuthorView
и написать немного лишнего материала. Это может выглядеть так:
def post(self, *args, **kwargs): import pdb; pdb.set_trace()
Имейте в виду, что, хотя DRF обеспечивает целостность базы данных, основанную на свойствах модели, мы не устанавливаем какую-либо безопасность для тех, кто может получить доступ или использовать эту форму. Вход безопасен, вход в систему и управление разрешениями выходит за рамки этой статьи, но достаточно сказать, что у DRF есть функции для доступа к просмотрам, с которыми вы работали, и это довольно банально для настроек.
Заканчиваем
Вы уже много узнали о платформе Django Rest Framework: как реализовать API-интерфейс для просмотра веб-страниц, который может вернуть JSON для вас, как настроить сериализаторы для составления и преобразования ваших данных, а также как использовать представления на основе классов для абстрагирования кода шаблона.
DRF имеет больше, чем несколько бит, которые мы смогли усвоить, но я надеюсь, что он вам будет полезен для вашего следующего приложения.