Django api rest: The Browsable API — Django REST framework

Содержание

Кратко о Django Rest Framework | Статьи о Джанго

Что такое Django Rest Framework?

Django Rest Framework (DRF) — это библиотека, которая работает со стандартными моделями Django для создания гибкого и мощного API для проекта. Эта статья поможет понять структуру DRF и дать вводные данные для начала его использования

Основная архитектура

API DRF состоит из 3-х слоев: сериализатора, вида и маршрутизатора.

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

Вид (ViewSet): определяет функции (чтение, создание, обновление, удаление), которые будут доступны через API.

Маршрутизатор: определяет URL-адреса, которые будут предоставлять доступ к каждому виду.

Сериализаторы

Модели Django интуитивно представляют данные, хранящиеся в базе, но API должен передавать информацию в менее сложной структуре. Хотя данные будут представлены как экземпляры классов Model, их необходимо перевести в формат JSON для передачи через API.

Сериализатор DRF производит это преобразование. Когда пользователь передает информацию (например, создание нового экземпляра) через API, сериализатор берет данные, проверяет их и преобразует в нечто, что Django может сложить в экземпляр модели. Аналогичным образом, когда пользователь обращается к информации через API, соответствующие экземпляры передаются в сериализатор, который преобразовывает их в формат, который может быть легко передан пользователю как JSON.

Наиболее распространенной формой, которую принимает сериализатор DRF, является тот, который привязан непосредственно к модели Django:


class ThingSerializer(serializers.ModelSerializer):
  class Meta:
    model = Thing
    
fields = (‘name’, )

Настройки fields позволяют точно указать, какие поля доступны этому сериализатору. В качестве альтернативы, может быть установлен exclude вместо fields, которое будет включать все поля модели, кроме тех, которые указаны в exclude.

Сериализаторы — это невероятно гибкий и мощный компонент DRF. Хотя подключение сериализатора к модели является наиболее распространенным, сериализаторы могут использоваться для создания любой структуры данных Python через API в соответствии с определенными параметрами.

Виды (ViewSets)

Сериализатор анализирует информацию в обоих направлениях (чтение и запись), тогда как ViewSet — это тот код, в котором определены доступные операции. Наиболее распространенным ViewSet является ModelViewSet, который имеет следующие встроенные операции:

  • Создание экземпляра: create ()
  • Получение / чтение экземпляра: retrieve ()
  • Обновление экземпляра (все или только выбранные поля): update () или partial_update ()
  • Уничтожение / Удаление экземпляра: destroy ()
  • Список экземпляров (с разбивкой по страницам по умолчанию): list ()

Каждая из этих функций может быть переопределена, если требуется другое поведение, но стандартная функциональность работает с минимальным кодом, а именно:



class ThingViewSet(viewsets.ModelViewSet):
    queryset = Thing.objects.all()

Если необходимы дополнительные настройки, можно использовать общие представления, вместо ModelViewSet или даже отдельные пользовательские представления.

Маршрутизаторы (роутеры)

И наконец, маршрутизаторы: они предоставляют верхний уровень API. Чтобы избежать создания бесконечных URL-адресов вида: «списки», «детали» и «изменить», маршрутизаторы DRF объединяют все URL-адреса, необходимые для данного вида в одну строку для каждого ViewSet, например:


# Инициализация роутера DRF. Только один раз на файл urls.py
# из маршрутизаторов импорта rest_framework

router = routers.', include (router.urls))

Теперь через API можно получить данные точно так же, как и любые другие обычные страницы Django.

Поделитесь с другими:

Что такое Django REST Framework?

Я написал эту статью, чтобы рассказать в ней теорию, которая будет необходима для изучения Django REST Framework. Информация, изложенная в этой статье, не является исчерпывающей в данной теме и показывает историю развития веб-приложений лишь отчасти. Я просто постараюсь объяснить, почему этот фреймворк — часть естественной эволюции веб-технологий, и как при помощи него мы можем по-новому решать старые задачи веб-разработки.

Чтобы ответить на вопрос, что же такое Django REST Framework, нужно разобраться со всей необходимой терминологией.

Framework

Создавая приложение или любой другой программный продукт, мы хотим делать это быстро и качественно. Проще этого добиться, используя опыт и наработки других разработчиков, ведь многие задачи, которые мы встречаем в процессе работы, уже были кем-то решены. По сути, использование фреймворка позволяет сосредоточится на задачах бизнеса и не задумываться над техническими деталями там, где это возможно. Нужно отрисовать кнопку на сайте? Сделать авторизацию или сброс пароля? Сохранить данные пользователя из формы на сайте в базу данных? Для этого всё уже готово — бери и пользуйся!

Также важно понимать отличия Framework от библиотеки. Это похожие вещи. В обоих случаях в Python вы должны установить нужный пакет, импортировать и пользоваться им. Разница в том, что библиотеку в проекте вы используете там, где нужно, и так, как вы хотите, а фреймворк сам определяет способ разработки приложения, то есть не только предоставляет удобные инструменты разработки в виде вспомогательных функций и классов, но и непосредственно формирует архитектуру проекта, создает структуру кода, проще говоря, определяет путь, по которому вы будете создавать свое приложение.

Django

На сегодняшний день наиболее функциональным фреймворком для создания веб-приложений на языке Python является фреймворк Django. Django можно назвать MVC-фреймворком, так он реализует взаимодействие пользователя и системы:

  • Model (хранит данные пользователя)

  • View (отображает данные пользователя)

  • Controller (принимает изменения данных от пользователя).

Внутри Django эта терминология звучит немного иначе, но суть остается той же.

Разработка Django началась в 2003 году программистами Adrian Holovaty и Simon Willison, а публичный релиз состоялся в 2005 году. Функционал фреймворка хорошо отвечал требованиям в веб-разработке того времени. Он активно развивается и до сих пор. Хотя этот фреймворк и считается довольно крупным и многофункциональным, сам по себе он не мог удовлетворить все запросы веб-разработчиков. За время его существования сторонними разработчиками было создано огромное множество библиотек и фреймворков в качестве дополнений к Django, которые упрощают реализацию тех или иных задач: аутентификация через социальные сети, кеширование данных, хранение файлов в облаке и многое другое. Некоторые из дополнений со временем сами стали частью проекта Django, как это произошло с библиотекой South, управляющей миграциями базы данных. Но большинство дополнений так и остались независимыми пакетами. Одним из них и является Django REST Framework, при помощи которого мы можем создавать Web API на основе Django.

Web API

Сегодня сеть интернет построена по принципу Клиент-Серверного взаимодействия. Клиент посылает запрос — Сервер ему отвечает. В случае, когда между собой общаются два Сервера, мы условно называем Клиентом того, который отправил запрос и ожидает ответ, а Сервером будет тот, кто принимает запрос и отвечает не него. Взаимодействие браузеров и веб-сайтов (первые выступают в роли Клиента, а вторые в роли Сервера) традиционно делалось при помощи технологии html-рендеринга, именно так изначально это делал Django. Чтобы получить данные с веб-сайта, браузер отправляет запрос GET к Серверу. Сервер формирует ответ в виде html-страницы и передает ее браузеру. Так Сервер передает данные браузеру, но как браузер может передать данные Серверу? В этой самой html-странице Сервер заложил все необходимые веб-формы, заполнив которые, пользователь мог бы передать свои данные обратно на сервер. Когда вы ввели свои данные в форму на сайте, бразуер отправляет Серверу запрос POST, в котором содержатся ваши данные, а Сервер обрабатывает их и записывает в базу данных.

Все это отлично работало, но уже в середине нулевых такой подход перестал удовлетворять возрастающим требования в веб-разработке. Появлялись мобильные приложения, различные гаджеты с доступом в интернет, и для них уже не подходил стандартный способ html-рендеринга на сервере, ведь теперь каждому клиенту нужно было отрисовать данные по-своему. Постоянно увеличивалось взаимодействие серверов друг с другом, и html-формат уже не подходил. Для всех этих задач есть другой способ обмена данными — Web API. Смысл этого способа в том, что Сервер передает Клиенту не html-страницу, а непосредственно данные, никак не влияя на то, как эти данные будут в итоге представлены. Наиболее популярными форматами для передачи данных становятся XML и JSON. Таким образом Сервер полностью избавляется от задачи отрисовки данных. Какое-то время длился переходный период, когда разработчикам веб-приложений на Сервере приходилось поддерживать оба способа одновременно: html рендерился на Сервере для браузеров, а Web API использовался для мобильных приложений и интеграции с другими серверами. Понятно, что разработчикам приложений на Сервере приходилось делать двойную работу. Но в начале десятых ситуация стала меняться в пользу Web API. Этому способствовало молниеносное развитие инструментов на языке JavaScript, а также появление различных веб-фреймворков, одним из которых и является предмет данной статьи.

Браузерные приложения быстро научились отрисовывать веб-страницы самостоятельно, получая чистые данные с Сервера. Веб-приложения на сервере научились создавать API быстро и легко. Так сформировалась четкое разделение на Backend и Frontend разработку: тех, кто поддерживает приложение на Сервере, и тех, кто делает браузерные (клиентские) приложения. А Web API стал универсальным способом общения для Сервера и всех его клиентов (браузеров, мобильных приложений, других Серверов). Конечно, это не могло не привести к развитию стандартов в общении между системами. И Клиенту, и Серверу необходимо знать каким образом общаться с друг с другом, как передавать данные, как сообщать об ошибках. Разработчики всегда могли договориться о том, как взаимодействовать их приложениям, но наличие некоего стандарта в веб-разработке позволило бы эту задачу облегчить. И вот в начале десятых таким стандартом стала концепция REST.

REST

В 2000 году Рой Филдинг написал докторскую диссертацию, где изложил концепцию REST. Там были рекомендации о том, как спроектировать Сервер, чтобы ему было удобно общаться с Клиентами. Выделю два главных принципа создания приложений в стиле REST:

  • Сервер не должен ничего знать о текущем состоянии Клиента. В запросе от Клиента должна быть вся необходимая информация для обработки этого запроса Сервером.
  • Каждый ресурс на Сервере должен иметь определенный Id, а также уникальный URL, по которому осуществляется доступ к этому ресурсу.

На данный момент мы можем найти фреймворк для создания приложений в стиле REST практически для каждого языка программирования, используемого в веб-разработке. Логика построения Web API на Сервере в этих фреймворках реализована одинаково.

Действия для управления данными привязаны к определенным HTTP-методам. Существует несколько стандартных действий для работы с данными — это Create, Read, Update, Delete. Часто их обобщают как CRUD.

  • Для создания объекта используется http-метод POST
  • Для чтения — http-метод GET
  • Для изменения — http-метод PUT
  • Для удаления — http-метод DELETE

Давайте представим сообщения от Клиента к Серверу через Web API в стиле REST .

У нас есть объект Кошка, и мы хотим создать запись о кошке на Сервере. Для этого мы отправляем запрос на сервер:

POST — http://www.pets-server.ru/cats/

С данными в теле запроса

Name: “My Best Cat”
Color: “Red”
Age: 2

Плюс к этому запросу (и все другим) будет добавлен ключ аутентификации.

“Auth-Token”: “IPjxTy7Lodas343Fswv2”

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

Сервер ответит на этот запрос вот таким сообщением:

Id: 21
Name: “My Best Cat”
Color: “Red”
Age: 2

Сервер взял все поля, переданные клиентом, и добавил к ним поле Id. Здесь работает правило REST, согласно которому каждый ресурс должен иметь уникальный идентификатор и быть доступным по определенному URL. Сервер создал ресурс и вернул нам его Id.

Теперь мы можем получить данную запись по URL

GET — http://www.pets-server.ru/cats/21

Ответ сервера:

Id: 21
Name: “My Best Cat”
Color: “Red”
Age: 2

Что, если Клиент хочет изменить созданные им данные на сервере?

Отправляем запрос:

PUT — http://www.pets-server.ru/cats/21

С телом запроса:

Id: 21
Name: “My Best Cat”
Color: “Black”
Age: 2

Ответ сервера:

Id: 21
Name: “My Best Cat”
Color: “Black”
Age: “2”

Метод PUT используется для изменения данных. Номер 21 в URL говорит о том, какой именно объект нужно изменить. Теперь наша кошка имеет цвет “Black”.

Для удаления записи на Сервере достаточно отправить запрос:

DELETE — http://www.pets-server.ru/cats/21

С телом запроса:

Тут также мы указываем в Id объекта в URL, но передавать никаких данных в теле запроса для удаления объекта уже не требуется.

Django REST Framework

Наконец, мы добрались до главной темы этой статьи. Мы вкратце разобрали каждый компонент этого словосочетания и теперь сможем понять, зачем использовать этот фреймворк, и какие задачи он решает.

Тут я бы хотел процитировать слова Тома Кристи, создателя Django REST Framework.

“Неудивительно, что Django REST framework — это API фреймворк для Django. И он пытается заполнить все пробелы в том, как исторически был спроектирован веб-фреймворк Django”.

И действительно, пусть Django был спроектирован давно, он до сих отлично решает свои задачи. Однако с появлением новых требований в веб-разработке, отсутствие компонентов для создания Web API воспринимается как пробел.

Django REST framework способен этот пробел заполнить.

А мы уже заполнили все пробелы в теории и терминологии и готовы перейти к практике!

Новые вопросы с меткой [django-rest-framework]

Django REST framework (DRF) — мощный и гибкий инструментарий для создания Web API, реализованный в виде приложения Django.

Не могу написать тест на создание поста. (DRF)

У меня есть тест на get запрос о списке всех постов, он прекрасно работает. Но я не могу сделать post запрос на создание тех самых постов. По началу была проблема в том что я не мог авторизоваться, но …

задан 5 часов назад

django reverse_related annotate and filter

I have 2 models class Model_one(Model): … class Model_two(Model): is_reserved = BooleanField() model_one = ForeignKey(Model_one, CASCADE) date = DatetimeField() …

задан 27 фев в 14:53

Terraxer

13222 серебряных знака77 бронзовых знаков

как соединить фронтэнд и бэкэенд?

Если django на бэке, а vue на фронте, то я просто по урлу через джанго отдаю index.hmtl с vue? url в django тогда регуляркой задать чтоб всегда на index.hmtl попадал? или это не правильный подход

задан 20 фев в 14:08

Ошибка деплоя на Heroku Nuxt + Django

Всем доброго времени суток. Делаю деплой NuxtJS+Django на heroku впервые, сам деплой происходит без проблем, но когда открываю по ссылке app то ошибка Application error. Ссылка на репо: https://github….

задан 15 фев в 18:32

Как сделать так, чтобы Django отдавал index.html Angular?

У меня есть проект Django + Angular со следующей структурой В папке application, я скомпилировал проект angular в папку dist. В папке dist — application есть index.html. Что мне сделать, чтобы Django …

задан 30 янв в 12:44

Alex Nikitin

21111 серебряный знак1212 бронзовых знаков

IntegrityError at /rooms/ UNIQUE constraint failed: office_room.id Django Rest Framework

Появилась проблема, мешающая продвигаться в обучении DRF дальше. В файле models.py есть модели, которые связаны один-ко-многим, один офис — несколько кабинетов (комнат). Создал для этих моделей свои …

задан 18 янв в 18:02


Django api rest фильтр manytomany



Я совсем новичок в Django и Django Api Rest FrameWork

Я пытаюсь разработать Api с двумя моделями, связанными с отношением ManyToMany

class Category(models.Model):
    name = models.CharField(max_length=100)

class Apartment(models.Model):
    id_2 = models.IntegerField(default= None)
    neighborhood = models.CharField(max_length=100)
    name = models.CharField(max_length=120)
    district = models.CharField(max_length=120)
    created = models.DateTimeField()
    cats = models.ManyToManyField(Category)
    address = models.CharField(max_length=200)
    postal_code = models.IntegerField()
    latitude = models.FloatField()
    longitude = models.FloatField()
class CategorySerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Category
        fields = ( 'id', 'name')

class AptSerializer(serializers.HyperlinkedModelSerializer):

    cats = CategorySerializer(many=True, read_only=True)

    class Meta:
        model = Apartment
        fields = ('id_2', 'neighborhood', 'name','district','created','cats','address','postal_code','latitude','longitude')
class AptViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Apartment.objects.all()
    serializer_class = AptSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('id_2', 'neighborhood', 'name', 'district','created','cats','address','postal_code','latitude','longitude')
router.register(r'apartments', views.AptViewSet)

Как вы можете видеть, он реализует DjangoFilterBackend , так что теперь я могу фильтровать с помощью типа URL-адресов

http://localhost:8000/apartments/?district=Eixample

и я получаю это

 {
    "id_2": 1044121532,
    "neighborhood": "la Nova Esquerra de l'Eixample",
    "name": "Hotel Exe AB Viladomat",
    "district": "Eixample",
    "created": "2001-02-13T00:00:00Z",
    "cats": [
        {
            "id": 1073,
            "name": "Allotjament"
        },
        {
            "id": 1075,
            "name": "Hotels"
        },
        {
            "id": 1076,
            "name": "3 estrelles"
        }
    ],
    "address": "Viladomat 197",
    "postal_code": 8015,
    "latitude": 41.383665702777776,
    "longitude": 2.151834694444444
},

Я хотел бы сделать запрос get как

http://localhost:8000/apartments/?cats_name=Hotels

Но это не работает, есть идеи, в какую сторону пойдет дорога отныне? Написать пользовательский фильтр? написать еще один ViewSet для объектов категории?

Спасибо

python django rest django-rest-framework
Поделиться Источник PereCullera     17 сентября 2015 в 17:28

2 ответа


  • Django Rest Framework (GET фильтр по полю ManyToMany)

    Я пытаюсь понять, как отфильтровать поле ManyToMany по значению. В Django это так же просто, как queryset.filter(m2mfield __name), но я не могу понять, чего мне не хватает. Я использую Django Rest Framework и DjangoFilterBackend . Модели : class City(models.Model): name =…

  • Django Rest Framework ManyToMany фильтр нескольких значений

    У меня есть две модели, одна определяет пользователей, другая определяет метки на этих пользователях. Я использую Django Rest Framework для создания API. Я хотел бы иметь возможность запрашивать пользователей по крайней мере с идентификаторами меток 1 и 2. Например, есть ли ярлыки пользователей:…



1

Корень QuerySet, предоставленный менеджером, описывает все объекты в таблице базы данных. Обычно, однако, вам нужно будет выбрать только подмножество полного набора объектов.

Но здесь вы передаете параметры запроса и фильтруете весь набор запросов

class AptViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Apartment.objects.all()
    serializer_class = AptSerializer

    def get_queryset(self):
        queryset = super(AptViewSet, self).get_queryset()
        cats_name = self.request.query_params.get('cat_name', None)
        if cats_name:
            queryset = queryset.filter(cats__name=cats_name)
        return queryset

Если вы можете следовать этому посту для написания пользовательских фильтров Как передать kwarg для фильтрации

Поделиться Seenu S     17 сентября 2015 в 19:08



0

Проверьте эту ссылку на фильтрацию параметров запроса.

Вы будете переопределять метод get_queryset в своем сериализаторе.

Поделиться Erik     17 сентября 2015 в 17:34


Похожие вопросы:


django-фильтр запросов на manytomany пуст

В Django есть ли способ фильтровать по пустому полю manytomany или null. class TestModel(models.Model): name = models.CharField(_(‘set name’), max_length=200) manytomany =…


django rest framework фильтр

Я работаю с API, сделанным из Django rest framework, Я пытаюсь сделать фильтр для JSON Это мой файл serializers.py from rest_framework import serializers from .models import…


Django rest framework фильтр с условием или

Я использую фильтр Django Rest Framework для доступа к своим данным. Мне нужно получить данные, которые отвечают одному из двух условий. Пример: Mywebsite/api/animal/?name=lion||name=frog || не…


Django Rest Framework (GET фильтр по полю ManyToMany)

Я пытаюсь понять, как отфильтровать поле ManyToMany по значению. В Django это так же просто, как queryset.filter(m2mfield __name), но я не могу понять, чего мне не хватает. Я использую Django Rest…


Django Rest Framework ManyToMany фильтр нескольких значений

У меня есть две модели, одна определяет пользователей, другая определяет метки на этих пользователях. Я использую Django Rest Framework для создания API. Я хотел бы иметь возможность запрашивать…


Azure REST API фильтр местоположения

Я пытаюсь GET отфильтровать ответы от Azure RM, используя REST API . Фильтр типа работает, но когда я пытаюсь получить его с помощью фильтра местоположения, он всегда накладывает неправильный фильтр…


Django REST или просто Django для REST API

Я хотел бы знать, можно ли построить REST Api, используя только Django (без Django REST). У меня есть следующий код в моем views.py my Django (no REST Django) from django.http import HttpResponse,…


Django ManyToMany полевой фильтр

Итак, у меня есть эта система, где мой объект Post имеет поле ManyToMany и называется Saves. Так что, например, на Reddit вы можете сохранить пост. Поэтому я заставил его работать, и пользователи…


Django REST Framework ManyToMany ошибка

Когда я добавляю сериализатор для поля ManyToMany, он отображает результаты на REST API, но когда я публикую данные, то сериализатор выдает is_valid() как ложь. Когда я упоминаю их как JSONFields,…


Django-REST-Framework REST API в приложении django

Мне интересно, есть ли способ получить доступ к REST API в приложении Django. Я создал REST API, используя Django rest framework. В том же проекте у меня есть еще одно приложение, в котором я хочу…

Introduction — django-rest-framework-russian-documentation

Django REST framework (DRF) — мощный и гибкий инструмент для построения Web API.

Вот несколько причин, чтобы использовать DRF:

  • Крайне удобная для разработчиков браузерная версия API;

  • Наличие пакетов для OAuth2a и OAuth3 авторизации;

  • Сериализация, поддерживающая ORM и не-ORM источники данных;

  • Возможность полной и детальной настройки — можно использовать обычные представления-функции, если вы не нуждаетесь в мощном функционале;

  • Расширенная документация и отличная поддержка сообщества;

  • Используется и пользуется уважением таких узнаваемых компаний, как Mozilla, Red Hat, Heroku, Eventbrite.

Существует пример API для тестирования, который доступен здесь доступно здесь.

У DRF следующие требования:

  • Django (1.11, 2.0, 2.1, 2.2)

Мы настоятельно рекомендуем и официально поддерживаем только последние версии патчей для каждой серии Python и Django.

Установите с помощью pip

pip install djangorestframework

Добавьте 'rest_framework' в INSTALLED_APPS в настройках:

INSTALLED_APPS = (

...

'rest_framework',

)

Давайте рассмотрим краткий пример использования инфраструктуры REST для создания простого API на основе модели для доступа к пользователям и группам.

Создайте новый проект:

pip install django

pip install djangorestframework

django-admin startproject example .

./manage.py migrate

./manage.py createsuperuser

Теперь отредактируйте модуль example/urls.py в вашем проекте:

from django.conf.urls import url, include

from django.contrib.auth.models import User

from rest_framework import routers, serializers, viewsets

class UserSerializer(serializers.HyperlinkedModelSerializer):

class Meta:

model = User

fields = ['url', 'username', 'email', 'is_staff']

class UserViewSet(viewsets.ModelViewSet):

queryset = User.objects.all()

serializer_class = UserSerializer

router = routers.DefaultRouter()

router.register(r'users', UserViewSet)

urlpatterns = [

url(r'^', include(router.api-auth/', include('rest_framework.urls', namespace='rest_framework'))

]

Мы также хотели бы настроить несколько параметров для нашего API.

Добавьте следующее к вашему settings.py модулю:

INSTALLED_APPS = [

...

'rest_framework',

]

REST_FRAMEWORK = {

'DEFAULT_PERMISSION_CLASSES': [

'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'

]

}

Вот и все, мы закончили!

Теперь можно открыть API в вашем браузере по адресу http://127.0.0.1:8000/, и увидеть ваше API 'users'. Так же, если вы воспользуетесь кнопкой 'Login' в верхнем правом углу и авторизуетесь, вы сможете добавлять, изменять и удалять пользователей из системы.

Вы также можете взаимодействовать с API с помощью инструментов командной строки, таких как curl. Например, чтобы вывести конечную точку пользователей:

$ curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/

[

{

"url": "http://127.0.0.1:8000/users/1/",

"username": "admin",

"is_staff": true,

}

]

Или создать нового пользователя:

$ curl -X POST -d username=new -d email=[email protected] -d is_staff=false -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/

{

"url": "http://127.0.0.1:8000/users/2/",

"username": "new",

"is_staff": false,

}

Не можете дождаться, чтобы начать? Руководство по быстрому старту — быстрейший способ.

Руководство проведет вас через все этапы настройки DRF. Это займет не очень много времени, однако вы получите полное понимание того, как все компоненты работают друг с другом и данное руководство крайне рекомендовано к прочтению.

  1. ​Сериализация​

  2. ​Запросы-ответы​

  3. ​Представления-классы​

  4. ​Аутентификация/права доступа​

  5. ​Отношения и связи​

  6. ​Наборы представлений и роутеры​

  7. ​Схемы и клиентские библиотеки​

Так же есть пример работающего API законченного руководства для тестовых целей, доступен здесь.

Навигатор по API — исчерпывающее руководство по всему функционалу, предоставляемому DRF.

Основные руководства для использующих DRF.

Прочтите руководство для разработчиков для получения информации о том, как склонировать репозиторий, запустить набор тестов и отправить изменения обратно в DRF.

Для поддержки обратитесь в группу обсуждения DRF или создайте вопрос на StackOverflow с указанием тэга ‘django-rest-framework’.

Для уведомления об обновлениях, подпишитесь на нас в Twitter.

Если вы уверены, что нашли пробел в безопасности, пожалуйста, не создавайте публичный баг-репорт!

Отправьте описание проблемы по почте [email protected]. Руководители проекта будут работать с вами для решения любых подобных проблем.

Пожалуйста, открывая Pull Request, указывайте меня в качестве ревьюера, так я буду узнавать об этом моментально.

Спасибо всем за помощь в переводе!

Перевод производится с помощью утилиты md_docs-trans-app​

Использование REST в Django | proft.me

Введение

REST (сокр. англ. Representational State Transfer, «передача состояния представления») — подход к архитектуре сетевых протоколов, обеспечивающих доступ к информационным ресурсам. Был описан и популяризован в 2000 году Ройем Филдингом (Roy Fielding), одним из создателей протокола HTTP. Самой известной системой, построенной в значительной степени по архитектуре REST, является современная Всемирная паутина. источник

Каждая сущность, с которой необходимо работать через REST, должна иметь уникальный url. Например, фильм «Неудержимые» идентифицируется по /film/1/. В REST каждая сущность называется ресурсом. Для манипуляций с ресурсом используются стандартные методы HTTP: GET, POST, PUT, DELETE, которые в REST называются интерфейсы:

GET /film/1/ — запрос фильма с id равным 1. В случае корректного запроса в ответ приходит 200/OK и запрашиваемые данные, в случае ошибки 400/Bad Request;

POST /film/1/ — изменение фильма, новые данные передаются в теле запроса. В случае запроса на изменение в ответ приходит 200/OK, в случаи успешного создания ресурса — 201/Created, в случае ошибки — 400/Bad Request;

DELETE /film/1/ — удаление фильма. В случае корректного запроса в ответ приходит 200/Accepted, если запрашиваемый ресурс отсутствует — 404/Not Found, если существует несколько фильмов с id=1 то вернется 409/Conflict;

Подробнее с REST можно познакомится по приведенным ссылкам:

Установка и использование

Из множества доступных реализаций REST в django я решил остановится на django-piston. Почему именно django-piston? На то есть две причины, во-первых, я встречал много лестных отзывов в западной блогосфере по-поводу piston, во-вторых, проект в котором надо было прикрутить REST писался на ExtJS (уже Sencha), а Matt Dorn описал у себя в блоге наглядный пример как объединить ExtJS и Django через REST. Сам пост и выступление Matt Dorn на одной из конференций можно найти ниже, в блоке Дополнительное чтиво.

В качестве примера напишем простую систему учета новых фильмов в кинотеатре. Начнем-с.

Устанавливаем последнюю версию django-piston

hg clone http://bitbucket.org/jespern/django-piston

В INSTALLED_APPS добавляем ‘piston’.

В корне проекта создадим директорию api (не забываем создать файл init.py). В этой же директории создадим файл handlers.py, в котором описываются интерфейсы работы с ресурсом, т.е. все манипуляции (CRUD) с нашей моделью Фильмов. Минимальное содержимое файла:

from piston.handler import BaseHandler
from films.models import Film

class FilmHandler(BaseHandler):
    model = Film
    fields = ('id', 'title', 'genre', 'release')

Для начала работы этого хватает, все остальное добавит базовый класс BaseHandler.api/’, include(‘api.urls’)), )

Создадим приложение films с такой моделью:

# coding=utf-8
from django.db import models

class Film(models.Model):
    title = models.CharField('Название', max_length=200)
    genre = models.CharField('Жанр', max_length=100)
    release = models.DateField('Дата релиза')

    def __unicode__(self):
        return self.title

Добавим новое приложение в INSTALLED_APPS и синхронизируем БД.

Добавим из консоли два тестовых фильма:

curl -i -X POST -d "title=The%20Expendables&genre=action&release=2010-01-28" http://127.0.0.1:8000/api/films/

HTTP/1.0 200 OK
Date: Tue, 07 Sep 2010 21:55:24 GMT
Server: WSGIServer/0.1 Python/2.6.5
Vary: Authorization
Content-Type: application/json; charset=utf-8

{
    "genre": "action", 
    "release": "2010-01-28", 
    "id": 1,
    "title": "The Expendables"
}

curl -i -X POST -d "title=The%20Karate%20Kid&genre=action&release=2010-01-28" http://127.0.0.1:8000/api/films/

HTTP/1.0 200 OK
Date: Tue, 07 Sep 2010 21:57:32 GMT
Server: WSGIServer/0.1 Python/2.6.5
Vary: Authorization
Content-Type: application/json; charset=utf-8

{
    "genre": "action", 
    "release": "2010-01-28", 
    "id": 2,
    "title": "The Karate Kid"
}

Все 200/OK, теперь запросим список фильмов:

curl -i -X GET http://127.0.0.1:8000/api/films/

HTTP/1.0 200 OK
Date: Tue, 07 Sep 2010 21:59:44 GMT
Server: WSGIServer/0.1 Python/2.6.5
Vary: Authorization
Content-Type: application/json; charset=utf-8

[
    {
        "genre": "action", 
        "release": "2010-01-28", 
        "id": 1,
        "title": "The Expendables"
    }, 
    {
        "genre": "action", 
        "release": "2010-01-28", 
        "id": 2,
        "title": "The Karate Kid"
    }
]

Удалим фильм с id = 2

curl -i -X DELETE http://127.0.0.1:8000/api/film/2/

HTTP/1.0 204 NO CONTENT
Date: Tue, 07 Sep 2010 22:05:55 GMT
Server: WSGIServer/0.1 Python/2.$', 'django.views.generic.simple.direct_to_template', {'template':'django_piston.html'}),

Скриншот полученной страницы:

На этом возможности django-piston не ограничиваются:

Накануне запуска поста обнаружил (в твитере у Александра Соловъёва) хороший инструмент для отладки REST API — htty

Новые подходы

Со времени первой публикации прошло уже много времени и появились новые инструменты, среди них:

Дополнительное чтиво

Документирование вашего API — Django REST framework

REST API должен тратить почти все свои описательные усилия на определение типа (ов) мультимедиа, используемого для представления ресурсов и управления состоянием приложения.

— Рой Филдинг, REST API должны быть гипертекстовыми

Фреймворк

REST предоставляет встроенную поддержку для генерации схем OpenAPI, которые может использоваться с инструментами, позволяющими создавать документацию по API.

Также доступен ряд отличных пакетов документации сторонних производителей.

Доступен ряд пакетов, позволяющих генерировать HTML страницы документации из схем OpenAPI.

Два популярных варианта — Swagger UI и ReDoc.

Для обоих требуется немного больше, чем расположение вашего файла статической схемы или динамическая конечная точка SchemaView .

Минимальный пример с Swagger UI

Предполагая, что вы следовали примеру из документации схем для маршрутизации динамический SchemaView , минимальный шаблон Django для использования пользовательского интерфейса Swagger может быть это:

  

  
     Чувство 
    
    
    
  
  
    
<сценарий> const ui = SwaggerUIBundle ({ url: "{% url schema_url%}", dom_id: '# чванство-ui', предустановки: [ SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset ], макет: "BaseLayout", requestInterceptor: (запрос) => { запрос.заголовки ['X-CSRFToken'] = "{{csrf_token}}" запрос на возврат; } })

Сохраните это в папке шаблонов как swagger-ui.html . Затем проложите маршрут TemplateView в URL-адресе вашего проекта conf:

  из django.views.generic import TemplateView

urlpatterns = [
    # ...
    # Route TemplateView для обслуживания шаблона пользовательского интерфейса Swagger.
    # * Предоставьте `extra_context` имя представления` SchemaView`.путь ('swagger-ui /', TemplateView.as_view (
        template_name = 'swagger-ui.html',
        extra_context = {'schema_url': 'openapi-schema'}
    ), name = 'swagger-ui'),
]
  

См. Документацию по пользовательскому интерфейсу Swagger для расширенного использования.

Минимальный пример с ReDoc.

Предполагая, что вы следовали примеру из документации схем для маршрутизации динамический SchemaView , минимальный шаблон Django для использования ReDoc может быть это:

  

  
     ReDoc 
    
    
    
    
    
    <стиль>
      тело {
        маржа: 0;
        отступ: 0;
      }
    
  
  
     
    
  

  

Сохраните это в папке шаблонов как redoc.html . Затем направьте TemplateView в URL-адресе вашего проекта conf:

  из django.views.generic import TemplateView

urlpatterns = [
    # ...
    # Route TemplateView для обслуживания шаблона ReDoc.
    # * Предоставьте `extra_context` имя представления` SchemaView`.
    путь ('redoc /', TemplateView.as_view (
        template_name = 'redoc.html',
        extra_context = {'schema_url': 'openapi-schema'}
    ), name = 'redoc'),
]
  

См. Документацию ReDoc для расширенного использования.

Существует ряд зрелых сторонних пакетов для предоставления документации по API.

drf-yasg — еще один генератор чванства

drf-yasg — это инструмент генерации Swagger, реализованный без использования предоставленной генерации схемы. от Django Rest Framework.

Он направлен на реализацию как можно большей части спецификации OpenAPI — вложенных схем, именованных моделей, тела ответов, валидаторы enum / pattern / min / max, параметры формы и т. д. — и для создания документов, которые можно использовать с кодом инструменты генерации, такие как swagger-codegen .

Это также превращается в очень полезную интерактивную программу просмотра документации в виде swagger-ui :

drf-impression — Разумная и гибкая генерация схемы OpenAPI 3.0 для Django REST framework

drf-Spectular — это инструмент для создания схемы OpenAPI 3 с явным акцентом на расширяемость, настраиваемость и создание клиентов. Шаблоны использования очень похожи на drf-yasg.

Он нацелен на извлечение как можно большего количества информации о схеме, обеспечивая при этом декораторы и расширения для упрощения настройка.Есть явная поддержка swagger-codegen, SwaggerUI и Redoc, i18n, управление версиями, аутентификация, полиморфизм (динамические запросы и ответы), параметры запроса / пути / заголовка, документация и многое другое. Также прямо из коробки поддерживаются несколько популярных плагинов для DRF.


Доступный для просмотра API, предоставляемый платформой REST, позволяет вашему API быть полностью самоописывающимся. Документацию для каждой конечной точки API можно получить, просто посетив URL-адрес в своем браузере.


Установка заголовка

Заголовок, который используется в доступном для просмотра API, генерируется из имени класса представления или имени функции. Любой завершающий суффикс View или ViewSet удаляется, а строка разделяется пробелами на границах верхнего / нижнего регистра или подчеркивании.

Например, представление UserListView будет называться User List при представлении в доступном для просмотра API.

При работе с наборами видов к каждому сгенерированному виду добавляется соответствующий суффикс.Например, набор представлений UserViewSet будет генерировать представления с именами User List и User Instance .

Настройка описания

Описание в доступном для просмотра API генерируется из строки документации представления или набора представлений.

Если установлена ​​библиотека python Markdown , то в строке документации можно использовать синтаксис уценки, и он будет преобразован в HTML в доступном для просмотра API. Например:

  класс AccountListView (views.APIView):
    "" "
    Возвращает список всех ** активных ** учетных записей в системе.

    Для получения более подробной информации о том, как активируются учетные записи, пожалуйста, [см. Здесь] [ref].

    [ref]: http://example.com/activating-accounts
    "" "
  

Обратите внимание, что при использовании наборов представлений базовая строка документации используется для всех сгенерированных представлений. Чтобы предоставить описания для каждого представления, например для списка и получения представлений, используйте разделы со строкой документации, как описано в Схемах как документация: Примеры.

ОПЦИИ
Метод API-интерфейсы

REST также поддерживают программно доступные описания с использованием HTTP-метода OPTIONS .Представление ответит на запрос OPTIONS метаданными, включая имя, описание и различные типы мультимедиа, которые оно принимает и отвечает.

При использовании общих представлений любые запросы OPTIONS будут дополнительно отвечать метаданными, касающимися любых доступных действий POST или PUT , описывающих, какие поля находятся в сериализаторе.

Вы можете изменить поведение ответа на запросы OPTIONS , переопределив метод просмотра options и / или предоставив собственный класс метаданных.Например:

  параметры def (self, request, * args, ** kwargs):
    "" "
    Не включайте описание представления в ответы OPTIONS.
    "" "
    meta = self.metadata_class ()
    data = meta.determine_metadata (запрос, сам)
    data.pop ('описание')
    вернуть данные
  

Дополнительные сведения см. В документации по метаданным.


Чтобы быть полностью RESTful, API должен представлять свои доступные действия как элементы управления гипермедиа в отправляемых им ответах.

В этом подходе вместо предварительного документирования доступных конечных точек API, описание концентрируется на используемых типах носителей .Доступные действия, которые могут быть выполнены с любым заданным URL-адресом, не являются строго фиксированными, но вместо этого становятся доступными благодаря наличию элементов управления ссылкой и формы в возвращенном документе.

Чтобы реализовать API гипермедиа, вам необходимо выбрать подходящий тип мультимедиа для API и реализовать настраиваемое средство визуализации и синтаксический анализатор для этого типа мультимедиа. Раздел документации, посвященный REST, Hypermedia и HATEOAS, включает указатели на фоновое чтение, а также ссылки на различные форматы гипермедиа.

запросов — Django REST framework

request.py

Если вы работаете с веб-сервисами на основе REST … игнорируйте request.POST.

— Малком Трединник, группа разработчиков Django

Класс Request фреймворка

REST расширяет стандарт HttpRequest , добавляя поддержку гибкого анализа запросов и аутентификации запросов фреймворка REST.


Объекты Request фреймворка

REST обеспечивают гибкий анализ запросов, который позволяет обрабатывать запросы с данными JSON или другими типами мультимедиа так же, как вы обычно обрабатываете данные формы.

request.data возвращает проанализированное содержимое тела запроса. Это похоже на стандартный запрос . Запрос POST и . ФАЙЛЫ атрибутов, за исключением того, что:

  • Он включает весь проанализированный контент, включая файловых и нефайловых входных данных.
  • Он поддерживает анализ содержимого HTTP-методов, отличных от POST , что означает, что вы можете получить доступ к содержимому запросов PUT и PATCH .
  • Он поддерживает гибкий анализ запросов инфраструктуры REST, а не просто поддерживает данные формы. Например, вы можете обрабатывать входящие данные JSON так же, как входящие данные формы.

Подробнее см. Документацию парсеров.

request.query_params — более правильно названный синоним для запроса .ПОЛУЧИТЬ .

Для ясности внутри кода мы рекомендуем использовать request.query_params вместо стандартного запроса Django . GET . Это поможет сделать вашу кодовую базу более правильной и очевидной — любой тип метода HTTP может включать параметры запроса, а не только запросы GET .

Класс APIView или декоратор @api_view гарантирует, что для этого свойства автоматически будет установлен список экземпляров Parser , на основе набора parser_classes , установленного в представлении, или на основе параметра DEFAULT_PARSER_CLASSES .

Обычно вам не нужен доступ к этому свойству.


Примечание: Если клиент отправляет искаженный контент, то доступ к request.data может вызвать ParseError . По умолчанию класс APIView инфраструктуры REST или декоратор @api_view перехватит ошибку и вернет ответ 400 Bad Request .

Если клиент отправляет запрос с типом содержимого, который не может быть проанализирован, будет вызвано исключение UnsupportedMediaType , которое по умолчанию будет перехвачено и вернет ответ 415 Unsupported Media Type .


Запрос предоставляет некоторые свойства, которые позволяют определить результат этапа согласования содержимого. Это позволяет реализовать такое поведение, как выбор разных схем сериализации для разных типов носителей.

Экземпляр средства визуализации, выбранный на этапе согласования содержимого.

Строка, представляющая тип мультимедиа, который был принят на этапе согласования содержимого.


Фреймворк

REST обеспечивает гибкую аутентификацию по запросу, что дает вам возможность:

  • Используйте разные политики аутентификации для разных частей вашего API.
  • Поддерживает использование нескольких политик аутентификации.
  • Укажите информацию о пользователе и токене, связанную с входящим запросом.

request.user обычно возвращает экземпляр django.contrib.auth.models.User , хотя его поведение зависит от используемой политики аутентификации.

Если запрос не аутентифицирован, значение по умолчанию request.user является экземпляром django.contrib.auth.модели.Анонимный пользователь .

Подробнее см. Документацию по аутентификации.

request.auth возвращает любой дополнительный контекст аутентификации. Точное поведение request.auth зависит от используемой политики аутентификации, но обычно это может быть экземпляр токена, по которому был аутентифицирован запрос.

Если запрос не прошел проверку подлинности или если дополнительный контекст отсутствует, значение по умолчанию — запрос.auth — это Нет .

Подробнее см. Документацию по аутентификации.

Класс APIView или декоратор @api_view гарантирует, что для этого свойства автоматически будет установлен список из Authentication экземпляров на основе authentication_classes , заданных в представлении, или на основе параметра DEFAULT_AUTHENTICATORS .

Обычно вам не нужен доступ к этому свойству.


Примечание: Вы можете увидеть ошибку WrappedAttributeError , возникающую при вызове .user или .auth свойства. Эти ошибки исходят от аутентификатора в виде стандартной AttributeError , однако необходимо, чтобы они были повторно вызваны как другой тип исключения, чтобы предотвратить их подавление внешним доступом к свойству. Python не распознает, что AttributeError исходит от аутентификатора, и вместо этого будет предполагать, что объект запроса не имеет свойства .user или .auth .Аутентификатор нужно будет исправить.


Инфраструктура REST

поддерживает несколько улучшений браузера, таких как формы PUT , PATCH и DELETE на основе браузера.

request.method возвращает строковое представление в верхнем регистре метода HTTP запроса.

Поддерживаются прозрачные формы PUT , PATCH и DELETE на основе браузера.

Для получения дополнительной информации см. Документацию по расширению браузера.

request.content_type , возвращает строковый объект, представляющий тип носителя тела HTTP-запроса, или пустую строку, если тип носителя не был предоставлен.

Обычно вам не нужно напрямую обращаться к типу контента запроса, поскольку вы обычно будете полагаться на поведение анализа запросов по умолчанию в REST framework.

Если вам действительно нужен доступ к типу содержимого запроса, вы должны использовать свойство .content_type вместо использования запроса .META.get ('HTTP_CONTENT_TYPE') , поскольку он обеспечивает прозрачную поддержку неформального содержимого на основе браузера.

Для получения дополнительной информации см. Документацию по расширению браузера.

request.stream возвращает поток, представляющий содержимое тела запроса.

Обычно вам не требуется прямой доступ к содержимому запроса, так как вы обычно будете полагаться на поведение анализа запросов по умолчанию в REST framework.


Поскольку запрос Request фреймворка REST расширяет HttpRequest Django, все другие стандартные атрибуты и методы также доступны.Например, словари request.META и request.session доступны в обычном режиме.

Обратите внимание, что по причинам реализации класс Request не наследуется от класса HttpRequest , а вместо этого расширяет класс с помощью композиции.

Создайте REST API с помощью Django — подход, основанный на тестировании: часть 1 — Scotch.io

Код без тестов не работает должным образом. — Джейкоб Каплан-Мосс

При разработке программного обеспечения тестирование имеет первостепенное значение.Так зачем мне это делать, спросите вы?

  • Тесты имеют короткий цикл обратной связи, что позволяет вам и вашей команде быстрее учиться и настраивать
  • Меньше времени тратится на отладку, что позволяет тратить больше времени на написание кода
  • Тесты действуют как документация для вашего кода!
  • Они улучшают качество кода и сокращают количество ошибок
  • После рефакторинга кода ваши тесты покажут, нарушило ли изменение ранее работавший код, и …
  • * Тесты могут предотвратить выпадение линии волос! *

Наилучший способ тестирования кода — это разработка через тестирование (TDD).

Вот как это работает:

  • Напишите тест. — Тест расширит некоторые функции вашего приложения
  • Затем запустите тест. — Тест должен завершиться неудачно, так как нет кода для его успешного прохождения.
  • Напишите код — Чтобы пройти тест
  • Запустите тест — Если он пройдет, вы уверены, что написанный вами код соответствует требованиям теста
  • Код рефакторинга — Удалите дублирование, удалите большие объекты и сделайте код более читабельным.Повторно запускайте тесты каждый раз при рефакторинге кода
  • Повторите — Вот и все!

Будучи поклонниками передового опыта, мы собираемся использовать TDD для создания bucketlist API. API будет иметь возможности CRUD (создание, чтение, обновление, удаление) и аутентификации. Тогда перейдем к делу!

Цель этой статьи — помочь вам узнать удивительные вещи при создании новых вещей. Мы будем создавать API списка ведра. Если вы не слышали о термине bucket list , это список всех целей, которых вы хотите достичь, мечты, которые вы хотите осуществить, и жизненный опыт, который вы хотите испытать, прежде чем умрет (или попадете в корзину).Таким образом, этот API должен помочь нам создавать наши списки задач и управлять ими.

Чтобы быть на одной странице, API должен иметь возможность:

  • Создать список корзины
  • Получить список корзины
  • Обновить
  • И, Удалить свой список ведра

Другие дополнительные функции, которые появятся позже:

  • Аутентификация пользователей API
  • Поиск в ведрах
  • Добавление элементов bucketlist в bucketlist
  • Пагинация
Новичок в Python, Django?

Если вы еще не работали с Django, ознакомьтесь с разделом Создание вашего первого приложения django.Это отличный ресурс для новичков.

Изучите Tailwind CSS с нуля

Теперь, когда мы знаем о bucketlist, вот немного об инструментах, которые мы будем использовать для создания его приложения.

Django Rest Framework (или просто DRF) — мощный модуль для создания веб-API. Очень легко создавать API-интерфейсы на основе модели, которые имеют политики аутентификации и доступны для просмотра.

Почему DRF?
  • Аутентификация — DRF является королем — от базовой аутентификации и аутентификации на основе сеанса до возможностей на основе токенов и Oauth3.
  • Сериализация — Он поддерживает источники данных как ORM, так и не-ORM и легко интегрируется с вашей базой данных.
  • Отличная документация — Если вы где-то застряли, вы можете обратиться к обширной онлайн-документации и отличной поддержке сообщества
  • Heroku, Mozilla, Red Hat и Eventbrite входят в число ведущих компаний, использующих DRF в своих API.
Требования

Для работы DRF необходимо иметь:

Создайте и вставьте компакт-диск в папку вашего проекта.Вы можете назвать папку как угодно.

  mkdir projects && $ _  

Затем создайте виртуальную среду, чтобы изолировать наш код от остальной системы.

  virtualenv -p / usr / local / bin / python3 venv  

Ключ -p указывает virtualenv путь к версии Python, которую вы хотите использовать. Убедитесь, что вы указали правильный путь установки python после переключателя -p. venv — это ваша среда. Несмотря на то, что вы можете назвать свою среду как угодно, рекомендуется просто назвать ее venv или env .

Активируйте свою виртуальную среду, выполнив следующие действия:

  источник venv / bin / активировать  

Вы увидите приглашение с именем среды. т.е. (venv) . Это означает, что среда теперь активна. Теперь мы готовы установить наши требования в нашу среду.

Внутри папки проектов установите Django с помощью pip

  $ pip install Django  

Если в вашей системе не хватает pip, просто выполните:

  sudo easy_install pip  

Поскольку нам нужно отслеживать наши требования, мы создадим файл requirements.txt файл.

  touch requirements.txt  

И добавьте установленные требования в текстовый файл, используя pip freeze

  pip freeze> requirements.txt  

Затем, наконец, создайте проект django.

  django-admin startproject djangorest  

Теперь у нас должна быть создана папка с именем djangorest . Не стесняйтесь давать ему любое другое имя. Структура папок должна выглядеть так:

  Джангорест
├─джангорест
│ ├── __init__.ру
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py  
Интеграция DRF

Используя pip, установите DRF

  pip install djangorestframework  

Чтобы наше приложение использовало DRF, нам нужно добавить rest_framework в наш settings.py . Давайте прямо и сделаем это.

 
...



INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'джанго.contrib.sessions ',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
]  

В Django мы можем создавать несколько приложений, которые объединяются в одно приложение. Приложение в django — это просто пакет python с кучей файлов, включая файл __init__.py .

Сначала cd в каталог djangorest на вашем терминале. Мы делаем это, чтобы получить доступ к файлу manage.py . Затем создайте приложение следующим образом:

  python3 управление.py startapp api  

Команда startapp создает новое приложение. Наше приложение называется api . Он будет содержать нашу логику API. Пока что у вас должна быть папка с именем api рядом с приложением djangorest .

Чтобы интегрировать наше приложение api с основным приложением djangorest , нам нужно добавить его в наш djangorest settings.py . Давайте прямо и сделаем это.

  ...



INSTALLED_APPS = [
    'джанго.contrib.admin ',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'api',
]  

Сначала тестируем!

Сначала мы хотим создать модели. Но у нас нет написанных тестов. Поэтому мы напишем несколько тестов в папке tests.py нашего приложения api.

 

из django.test импортировать TestCase
из .models import Bucketlist


класс ModelTestCase (TestCase):
    "" "Этот класс определяет набор тестов для модели bucketlist."" "

    def setUp (сам):
        "" "Определите тестовый клиент и другие тестовые переменные." ""
        self.bucketlist_name = "Напишите код мирового класса"
        self.bucketlist = Bucketlist (name = self.bucketlist_name)

    def test_model_can_create_a_bucketlist (самостоятельно):
        "" "Протестируйте модель bucketlist, можно создать bucketlist." ""
        old_count = Bucketlist.objects.count ()
        self.bucketlist.save ()
        new_count = Bucketlist.objects.count ()
        self.assertNotEqual (old_count, new_count)  

Приведенный выше код импортирует тестовый пример из django.тест. В тестовом примере есть единственный тест, который проверяет, может ли модель создать список корзины с именем.

Затем мы определяем наши модели

Нам нужно создать пустой класс модели. Это сделано в наших моделях .py

 

из моделей импорта django.db


класс Bucketlist (models.Model):
    перевал  

Выполнить тест с django очень просто. Мы будем использовать тестовую команду следующим образом:

  тест python3 manage.py  

Вы должны увидеть кучу ошибок по всему экрану.Не беспокойся об этом. Это потому, что мы еще не написали поля нашей модели и не обновили нашу базу данных. Django использует SQlite в качестве базы данных по умолчанию, поэтому мы будем использовать его сейчас. Кроме того, нам не нужно писать ни одного оператора SQL при создании моделей. Все это за нас делает Django. В файле models.py мы определим поля, которые будут представлять поля таблицы в нашей базе данных.

 

из моделей импорта django.db


класс Bucketlist (models.Model):
    "" "Этот класс представляет модель списка корзины."" "
    name = models.CharField (max_length = 255, blank = False, unique = True)
    date_created = models.DateTimeField (auto_now_add = True)
    date_modified = models.DateTimeField (auto_now = True)

    def __str __ (сам):
        "" "Вернуть удобочитаемое представление экземпляра модели." ""
        вернуть "{}". format (self.name)  

Мигрируем!

Миграции — это способ Django распространять изменения, которые вы вносите в свои модели (например, добавление поля, удаление модели и т. Д.), В схему вашей базы данных.Теперь, когда у нас есть обширная модель, нам нужно указать базе данных создать соответствующую схему. В консоли запустите это:

  python3 manage.py makemigrations  

Это создает новую миграцию на основе изменений, которые мы внесли в нашу модель. Затем примените миграции к своей базе данных, выполнив следующие действия:

  python3 manage.py миграция  

Когда вы запустите тесты, вы должны увидеть что-то вроде этого:

Тест пройден! Это означает, что мы можем приступить к написанию сериализаторов для нашего приложения

.

Сериализаторы сериализуют и десериализуют данные.Так что же все это значит, спросите вы? Сериализация — это изменение данных из сложных наборов запросов из БД в форму данных, которые мы можем понять, например JSON или XML. Десериализация возвращает этот процесс после проверки данных, которые мы хотим сохранить в БД.

Сериализаторы моделей
— это круто!

Класс ModelSerializer позволяет автоматически создавать класс сериализатора с полями, соответствующими полям модели. Это значительно сокращает количество строк кода. Создайте файл с именем сериализаторы .py внутри каталога api. Напишем в него код:

 

из сериализаторов импорта rest_framework
из .models import Bucketlist


класс BucketlistSerializer (сериализаторы.ModelSerializer):
    "" "Сериализатор для отображения экземпляра модели в формат JSON." ""

    класс Мета:
        "" "Мета-класс для сопоставления полей сериализатора с полями модели." ""
        model = Bucketlist
        fields = ('id', 'name', 'date_created', 'date_modified')
        read_only_fields = ('date_created', 'date_modified')  

Сначала напишем тесты представления.Поначалу написание тестов кажется сложной задачей. Однако легко узнать, что тестировать, если вы знаете, что реализовать. В нашей ситуации мы хотим создать представления, которые будут обрабатывать следующее:

  • Создание списка ведра — обработка запроса POST
  • Чтение списка (ов) — Обработка запроса GET
  • Обновление списка ведра — обработка запроса PUT
  • Удалить список ведра — обработать запрос на УДАЛЕНИЕ

Исходя из вышеперечисленных функций, мы знаем, что тестировать. Мы будем использовать их в качестве руководства.Возьмем первый случай. Если мы хотим проверить, успешно ли API создаст список корзины, мы напишем следующий код в tests.py :

 


из rest_framework.test импорт APIClient
из статуса импорта rest_framework
из django.core.urlresolvers импортировать обратный


класс ViewTestCase (TestCase):
    "" "Набор тестов для представлений API." ""

    def setUp (сам):
        "" "Определите тестовый клиент и другие тестовые переменные." ""
        self.client = APIClient ()
        себя.bucketlist_data = {'name': 'На Ибицу'}
        self.response = self.client.post (
            обратный ('создать'),
            self.bucketlist_data,
            format = "json")

    def test_api_can_create_a_bucketlist (самостоятельно):
        "" "Проверьте, есть ли у api возможность создания корзин." ""
        self.assertEqual (self.response.status_code, status.HTTP_201_CREATED)  

Этот тест не проходит, когда мы его запускаем. Хорошо. Это происходит потому, что мы не реализовали представления и URL-адреса для обработки запроса POST.

Давайте продолжим и реализуем их! На views.py напишите следующий код:

 

из rest_framework импортировать дженерики
из .serializers import BucketlistSerializer
из .models import Bucketlist


класс CreateView (generics.ListCreateAPIView):
    "" "Этот класс определяет поведение создания нашего API-интерфейса rest." ""
    queryset = Bucketlist.objects.all ()
    serializer_class = BucketlistSerializer

    def perform_create (self, сериализатор):
        "" "Сохраните данные поста при создании нового списка."" "
        serializer.save ()  

ListCreateAPIView — это общее представление, которое предоставляет обработчики методов GET (список всех) и POST

Обратите внимание, что мы указали атрибуты queryset и serializer_class . Мы также объявляем метод perform_create , который помогает сохранять новый список ведер после публикации.

Для полноты мы укажем URL-адреса в качестве конечных точек для использования нашего API.bucketlists / $ ‘, CreateView.as_view (), name = «create»), } urlpatterns = format_suffix_patterns (urlpatterns)

format_suffix_pattern позволяет нам указывать формат данных (необработанный json или даже html), когда мы используем URL-адреса. Он добавляет формат, который будет использоваться к каждому URL-адресу в шаблоне.

Наконец, мы добавляем URL-адрес в файл urls.py основного приложения, чтобы он указывал на наше приложение API. Нам нужно будет включить api.urls , который мы только что объявили выше, в основное приложение urlpatterns .’, включить (‘ api.urls ‘)) ]

Мы запустим наш сервер в стиле django с помощью команды runserver :

  python3 manage.py сервер запуска  

Вы должны увидеть этот вывод на своей консоли. Это означает, что все идет гладко.

Введите указанный сервером URL (http://127.0.0.1:8000/bucketlists) в своем браузере. И альт — работает! Напишите список желаний и нажмите кнопку публикации, чтобы убедиться, что наш API работает.Вы должны увидеть что-то вроде этого:

Написание тестов

Мы напишем еще три теста для обработки запросов GET , PUT и DELETE . Обернем их так:

 

    def test_api_can_get_a_bucketlist (самостоятельно):
        "" "Проверить, может ли api получить заданный список ведра." ​​""
        bucketlist = Bucketlist.objects.get ()
        response = self.client.get (
            обратный ('подробности',
            kwargs = {'pk': список ведра.id}), format = "json")

        self.assertEqual (response.status_code, status.HTTP_200_OK)
        self.assertContains (ответ, список ведра)

    def test_api_can_update_bucketlist (самостоятельно):
        "" "Проверить, может ли api обновлять заданный список ведра." ​​""
        change_bucketlist = {'name': 'Что-то новое'}
        res = self.client.put (
            reverse ('подробности', kwargs = {'pk': bucketlist.id}),
            change_bucketlist, формат = 'json'
        )
        self.assertEqual (res.status_code, status.HTTP_200_OK)

    def test_api_can_delete_bucketlist (самостоятельно):
        "" "Проверьте, может ли API удалить список ведра."" "
        bucketlist = Bucketlist.objects.get ()
        ответ = self.client.delete (
            reverse ('подробности', kwargs = {'pk': bucketlist.id}),
            format = 'json',
            follow = True)

        self.assertEquals (response.status_code, status.HTTP_204_NO_CONTENT)  

Если мы запустим эти тесты, они не пройдут. Давай исправим это. Пришло время дополнить api обработчиками методов PUT и DELETE . Мы определим для этого класс представления. На просмотров.py добавьте следующий код:

 


класс DetailsView (generics.RetrieveUpdateDestroyAPIView):
    "" "Этот класс обрабатывает HTTP-запросы GET, PUT и DELETE." ""

    queryset = Bucketlist.objects.all ()
    serializer_class = BucketlistSerializer  

RetrieveUpdateDestroyAPIView — это общее представление, которое предоставляет обработчики методов GET (один), PUT , PATCH и DELETE .

Наконец, мы создаем этот новый URL-адрес, который будет связан с нашим DetailsView.bucketlists / (? P [0-9] +) / $ ‘, DetailsView.as_view (), name = «details»),

Введите указанный URL-адрес (http://127.0.0.1:8000/bucketlists/1/) в своем браузере. И вуаля! — Оно работает! Теперь вы можете редактировать существующий список ведер.

Уф! Поздравляем с тем, что вы дочитали эту статью до конца — вы молодцы!

Во второй части серии мы углубимся в добавление пользователей, интеграцию авторизации и аутентификации, документирование API и добавление более сложных тестов.Хотите копнуть глубже? Не стесняйтесь читать больше в официальной документации DRF.

И если вы новичок в Django, я считаю Django для начинающих отличным.

Понравилась эта статья? Подпишитесь на @jeegik в Twitter

Как создать API на Python (Учебное пособие по Django REST API)

Сегодня в этом руководстве мы рассмотрим следующее:

  1. Как начать проект в Django.
  2. Как доставить JSON запрашивающей стороне из нашего нового API.
  3. Как развернуть наш новый API Django в Heroku.
  4. Как включить наш новый API в рынок RapidAPI.

Запустите проект Django

Сначала мы собираемся создать новый проект Django под названием rapid-api-practice. Затем в рамках этого проекта мы создадим новое приложение под названием api. Хотя поначалу это может показаться странным, «способ Django» заключается в размещении приложения или, что более вероятно, нескольких приложений в одном «проекте».

Мы поместим все это в корневой каталог с именем проекта из командной строки, например:

 mkdir rapid-api-practice
cd rapid-api-practice 

ПРИМЕЧАНИЕ : Настоятельно рекомендуется, но не обязательно, создавать виртуальный env в корневом каталоге.

Затем мы установим Django (порядок имеет значение при использовании venv):

 pip3 install django 

И, наконец, мы можем настроить наш новый проект с нашим единственным приложением, api. Обратите внимание на расширение. в команде, которая сообщает Django разместить проект в вашем текущем рабочем каталоге.

 django-admin startproject rapidapipractice. 

Затем из недавно созданного каталога проекта rapidapipractice запустите:

 django-admin startapp api 

Это должно оставить вас с деревом файлов, которое теперь должно выглядеть примерно так:

Затем мы можем настроить нашу базу данных, выполнив нашу первую миграцию:

 python3 manage.Py makemigrations
python3 manage.py migrate 

Наконец, нам нужно создать нашего первого пользователя. Давайте назовем этого пользователя admin и установим для него пароль password. В терминале запустите:

 python3 manage.py createduperuser
Имя пользователя: admin
Адрес электронной почты: [электронная почта защищена]
Пароль: ********
Пароль снова): ********
Этот пароль слишком распространен.
Обойти проверку пароля и все равно создать пользователя? [да / нет]: да
Суперпользователь успешно создан. 

Создайте наш API

Хорошо, теперь, когда наша уборка завершена, давайте перейдем к написанию нашего собственного кода.В этом примере мы просто воспользуемся встроенными в Django моделями User и Group, которые позволят нам без особых проблем продемонстрировать преобразование записей SQL в удобный для браузера JSON.

Далее, чтобы ускорить и упростить разработку, мы собираемся использовать модуль Django Rest Framework. Для установки просто запустите:

 pip3 install djangorestframework 

Сериализаторы (serializers.py)

Сначала мы собираемся определить некоторые сериализаторы, которые позаботятся о преобразовании SQL в JSON, которое мы ищем.Django Rest Framework также может обрабатывать другие сериализации, такие как XML и т. Д., Но мы собираемся использовать JSON. Если вы использовали Marshmallow для сериализации во Flask, это покажется вам знакомым. Давайте создадим в нашем каталоге api новый модуль с именем serializers.py, который мы будем использовать для наших представлений данных.

В командной строке:

 cd rapidapipractice / api && touch serializers.py 

Затем в теле нашего нового файла serializers.py введите следующее:

 from django.contrib.auth.models импорт пользователя, группы
из сериализаторов импорта rest_framework


класс UserSerializer (сериализаторы.HyperlinkedModelSerializer):
    класс Мета:
        model = Пользователь
        fields = ['url', 'username', 'email', 'groups']


класс GroupSerializer (сериализаторы.HyperlinkedModelSerializer):
    класс Мета:
        model = Группа
        fields = ['url', 'name'] 

Хотя Django Rest Framework предлагает множество различных типов отношений, в этом случае мы используем гиперссылки, настраивая сериализаторы Django Rest Framework для расширения HyperlinkedModelSerializer.Этот выбор дает нам следующее:

  • По умолчанию не включает поле идентификатора .
  • Он включает интерактивное поле URL-адреса, которое будет выполнять последующий запрос при нажатии.

Представления (views.py)

Теперь мы собираемся определить наши представления (или, точнее, наборы представлений), чтобы отправлять данные из нашего внутреннего интерфейса в браузер. Откройте api / views.py и вставьте следующее:

 из django.contrib.auth.models import User, Group
из rest_framework импортных наборов
Из .сериализаторы импортируют UserSerializer, GroupSerializer


класс UserViewSet (viewsets.ModelViewSet):
    "" "
    Конечная точка API, позволяющая просматривать или редактировать пользователей.
    "" "
    queryset = User.objects.all (). order_by ('- date_joined')
    serializer_class = UserSerializer


класс GroupViewSet (viewsets.ModelViewSet):
    "" "
    Конечная точка API, позволяющая просматривать или редактировать группы.
    "" "
    queryset = Group.objects.all ()
    serializer_class = GroupSerializer
 

Итак, для стандартных операций CRUD в базе данных SQL Django Rest Framework предоставляет нам эти наборы представлений, которые принимают и обрабатывают запросы GET, POST, PUT и DELETE.Они также позволяют одной конечной точке обрабатывать запросы на представление списков объектов в базе данных, а также отдельные экземпляры объектов. Довольно мило, правда.

Если по какой-то причине нам понадобится более детальный контроль над данными, которые наш API возвращает при конкретном запросе, мы можем разбить наши наборы представлений на чистые представления, но в случае, если эти наборы будут удовлетворять потребностям варианта использования, это предпочтительное средство.

URL-адресов (urls.py)

Хорошо, теперь нам нужно указать Django, какие представления возвращать для определенного маршрута.Для этого мы импортируем include и path из модуля django.urls, а также маршрутизаторы из Django Rest Framework и, конечно же, представления, которые должны быть возвращены. Все это можно сделать, включив следующий код в наш файл urls.py.

 из django.urls import include, path
из роутеров импорта rest_framework
из Rapidapipractice.api импортных представлений

router = routers.DefaultRouter ()
router.register (r'users ', views.UserViewSet)
router.register (r'groups ', views.GroupViewSet)

# Настроить автоматическую маршрутизацию URL
# Кроме того, мы включаем URL-адреса для входа в доступный для просмотра API.urlpatterns = [
    путь ('', включить (router.urls)),
    путь ('api-auth /', include ('rest_framework.urls', namespace = 'rest_framework'))
] 

Поскольку мы используем наборы представлений вместо представлений, мы можем автоматически сгенерировать URL conf для нашего API, зарегистрировав наборы представлений в нашем классе маршрутизатора.

Наконец, мы добавили представления входа и выхода по умолчанию для использования с просматриваемым API. Это необязательно, но полезно, если ваш API требует аутентификации и вы хотите использовать доступный для просмотра API.

Разбивка на страницы (settings.py)

Разбивка на страницы позволяет вам контролировать, сколько объектов на странице будет возвращено. Чтобы включить его, добавьте следующие строки в rapidapipractice / settings.py

 REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10
} 

Установленные приложения (settings.py)

Помните идею добавления нескольких приложений в данный проект? Наш API и Django Rest Framework — именно такие приложения.Чтобы использовать их в нашем проекте Django, нам нужно добавить «api» и «rest_framework» в список INSTALLED_APPS в api / settings.py, например:

 INSTALLED_APPS = [
  ‘Django.contrib.admin’,
  ‘Django.contrib.auth’,
  ‘Django.contrib.contenttypes’,
  ‘Django.contrib.sessions’,
  ‘Django.contrib.messages’,
  ‘Django.contrib.staticfiles’,
‘Api’,
  ‘Rest_framework’,
] 

Подготовка к развертыванию в Heroku

Создайте репозиторий Git в любом месте и зафиксируйте свою работу.Детали доступа к репо нам понадобятся позже, чтобы передать наш API на Heroku.

Procfile (procfile)

Создайте файл procfile в корне вашего репо. Он сообщит Heroku, что это веб-сервер dyno , который должен запускать gunicorn вместе с местоположением нашей точки входа wsgi. Вставив следующую строку в тело файла, мы закончим:

 web: gunicorn rapidapipractice.wsgi --log-file - 

Конфигурация базы данных (settings.py)

Мы собираемся настроить уровень хобби для Heroku postgres , потому что он бесплатный, Django поддерживает его и добавляется автоматически. Более того, нам придется отказаться от базы данных SQLite по умолчанию, которая поставляется с Django из коробки, потому что Heroku не поддерживает файловую базу данных. Он будет просто удалять его каждый раз при перезапуске приложения.

Откройте /api/settings.py и скопируйте следующую конфигурацию в конец файла:

 # Heroku: Обновите конфигурацию базы данных из $ DATABASE_URL.импортировать dj_database_url
db_from_env = dj_database_url.config (conn_max_age = 500) БАЗЫ ДАННЫХ ['по умолчанию']. обновление (db_from_env)
 

Требования (requirements.txt)

Heroku прочитает ваш файл requirements.txt, чтобы узнать, что ему нужно сделать доступным в вашей производственной среде. В нем должно быть указано следующее (версии могут отличаться):

 Django == 2.2.5
djangorestframework == 3.10.3
pytz == 2019.2
sqlparse == 0.3.0
URL-адрес базы данных dj == 0.5.0
пулеметчик == 19.9.0
psycopg2-binary == 2.7.7 

Примечание : обычно рекомендуется, чтобы, хотя мы не использовали большинство этих модулей локально, мы должны пойти дальше и установить их в нашем виртуальном окружении, чтобы мы могли просто запустить `pip freeze` для генерации полный и версионный список зависимостей, которые понадобятся Heroku. Тем не менее, вы также можете просто вставить приведенное выше в файл, который вы создаете в корне вашего репо, с именем requirements.txt.

Среда выполнения (runtime.txt)

Затем нам нужно создать нашу среду выполнения.txt в нашем корневом каталоге. Он просто сообщает Heroku, какой язык и версию мы используем.

 python-3.7.0 

Теперь мы должны быть готовы начать развертывание нашего API на Heroku.

Как опубликовать свой API на Heroku

1. Зарегистрируйте учетную запись Heroku

Heroku — это действительно изящный сервис, предлагающий бесплатный хостинг для хобби-проектов. Вы можете создать бесплатную учетную запись на сайте www.heroku.com.

2. Установите клиент Heroku локально

Следуйте этим инструкциям, чтобы загрузить и установить клиент локально.

3. Войдите в Heroku CLI

 heroku login 

Затем Heroku предоставит ссылку на графический интерфейс входа в систему, где вы можете войти.

4. Создайте и загрузите приложение

Если вы еще не тем не менее, вам нужно будет создать репозиторий Git и зафиксировать свою работу.

Чтобы создать приложение, мы запускаем команду «create» в корневом каталоге нашего репозитория git. Это создает git remote («указатель на удаленный репозиторий») с именем heroku в нашей локальной среде git.

 heroku create rapid-api-Practice 

Django Rest Framework имеет приятный графический интерфейс из коробки, но, поскольку мы собираемся добавить его в RapidAPI, мы просто пропустим обслуживание статических файлов, связанных с проект (т.е. CSS).

 heroku config: set DISABLE_COLLECTSTATIC = 1 

Затем мы можем отправить наше приложение в репозиторий Heroku, как показано ниже. Это загрузит приложение, упакует его в дино, запустит collectstatic и запустит сайт.

 git push heroku master 

Это сгенерирует URL-адрес, по которому нам нужно будет перейти, чтобы просмотреть наше приложение.Затем нам нужно будет добавить этот URL в список принятых хостов Django. Итак, давайте продолжим и адрес dd Heroku (например, «rapid-api-practice.herokuapp.com») для ALLOWED_HOSTS в Settings.py

. Хотя API теперь должен «работать», нам нужно перенести наши модели на настроить нашу базу данных.

 heroku run python manage.py migrate 

Затем позвольте Heroku создать суперпользователя администрирования:

 heroku run python manage.py createduperuser 

Теперь мы можем посмотреть на сайт.Это должно работать, хотя единственной записью будет только что созданный суперпользователь:

 heroku open 

Создайте несколько пользователей, группы и альбомы на сайте администратора и проверьте, ведет ли сайт должным образом.

5. Управление надстройками

Чтобы просмотреть надстройки, связанные с вашим приложением, используйте команду heroku addons. Здесь будут перечислены все дополнения, их ценовой уровень и состояние:

 (env) [email protected] ~ / rapid-api-practice $ / snap / bin / heroku addons
Состояние цены плана надстройки
───────────────- ───── ───── ────
heroku-postgresql (postgresql-rectangular-94269) hobby-dev бесплатно создано
 └─ как БАЗА ДАННЫХ
 
В таблице выше показаны надстройки и вложения к текущему приложению (quick-api-practice) или другим приложениям.

6. Установка переменных конфигурации

Вы можете просмотреть переменные конфигурации для своего приложения, выполнив команду heroku config. Ниже вы можете видеть, что у нас есть две переменные: DATABASE_URL, используемая для настройки нашей базы данных, и DISABLE_COLLECT_STATIC, которая сообщает Heroku, что ей не нужно беспокоиться об обслуживании CSS.

> heroku config === api Config Vars DATABASE_URL: postgres: // uzfnbcyxidzgrl: [электронная почта защищена] s.com:5432/dbftm4qgh4kda3
DISABLE_COLLECT_STATIC = 1 

Нам нужно будет установить наш секретный ключ Django на что-то действительно секретное, и нам нужно будет установить DEBUG в значение False в настройках.py, поэтому мы не передаем никакие частные обратные ссылки зрителям.

После внесения этих изменений мы можем перестроить наше приложение, запустив:

 git push heroku master 

7. Добавьте наше приложение в RapidAPI

Хорошо, добро пожаловать. Теперь, когда у нас есть URL-адрес, мы можем перейти к RapidAPI и добавить наше приложение на рынок. Щелкните Мои API.

Нажмите «Добавить новый API» на левой боковой панели.

На этом этапе у нас будет возможность импортировать файл Swagger или вручную определить наши конечные точки и тому подобное.Для простоты мы пока сделаем это вручную.

Наконец, нам нужно будет выполнить следующие шаги. Это займет всего несколько минут.

И шаззам ! Мы создали Django API с полной функциональностью CRUD, развернули его на Heroku и добавили в RapidAPI Marketplace !!

Следующие шаги:

Изучите RapidAPI, чтобы расширить функциональность вашего нового API.

Ссылки по теме

Django REST Framework API Key

Введение

Django REST Framework API Key — это мощная библиотека, позволяющая клиентам на стороне сервера безопасно использовать ваш API. Эти клиенты обычно представляют собой сторонние серверы и службы (например, машины ), у которых нет учетной записи пользователя, но которые все же должны безопасно взаимодействовать с вашим API.

Характеристики

  • ✌️ Простота использования : создавайте, просматривайте и отзывайте ключи API через сайт администратора или используйте встроенные помощники для программного создания ключей API.
  • 🔒 Максимально безопасный : ключи API обрабатываются так же тщательно, как и пароли пользователей.Перед сохранением в базе данных они хешируются с использованием хеш-кода паролей по умолчанию и видны только при создании.
  • 🎨 Настраиваемый : удовлетворяйте определенные бизнес-требования, создавая собственные модели ключей API, классы разрешений и панели администратора.

Стоит ли использовать ключи API?

Есть важные аспекты безопасности, которые необходимо учитывать перед переходом на схему управления доступом с помощью ключа API. Мы перечислили некоторые из них в разделе «Предупреждения о безопасности», включая обслуживание вашего API через HTTPS.

Кроме того, см. Почему и когда использовать ключи API, чтобы узнать, подходят ли ключи API вашему варианту использования.

Ключи API

идеальны в следующих ситуациях:

  • Блокировка анонимного трафика.
  • Реализация регулирования на основе ключей API. (Обратите внимание, что в Django REST Framework уже есть встроенные утилиты для этого варианта использования.)
  • Определение шаблонов использования путем регистрации информации запроса вместе с ключом API.

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

Предупреждение

Обратите внимание, что этот пакет НЕ предназначен для аутентификации. Вы НЕ должны использовать этот пакет для прямой или косвенной идентификации отдельных пользователей.

Если вам нужна межсерверная аутентификация, вы можете вместо этого рассмотреть OAuth. Могут помочь такие библиотеки, как django-oauth-toolkit.

Быстрый старт

Установить с трубкой :

  pip install "djangorestframework-api-key == 2. *"
  

Важно

Настоятельно рекомендуется привязать вашу зависимость к последней основной версии (как показано выше), поскольку критические изменения могут произойти и будут происходить между основными выпусками.

Добавьте приложение в свой INSTALLED_APPS :

  # settings.py

INSTALLED_APPS = [
  # ...
  "rest_framework",
  "rest_framework_api_key",
]
  

Выполните включенные миграции:

Чтобы узнать, как настраивать разрешения и управлять ключами API, обратитесь к Руководству пользователя.

django-json-api / django-rest-framework-json-api: поддержка JSON API для Django REST Framework

Обзор

Поддержка JSON API для Django REST Framework

По умолчанию Django REST Framework выдаст такой ответ:

 {
    «count»: 20,
    "следующий": "http: // пример.com / api / 1.0 / identity /? page = 3 ",
    "предыдущий": "http://example.com/api/1.0/identities/?page=1",
    "полученные результаты": [{
        "id": 3,
        "имя пользователя": "Джон",
        "full_name": "Джон Колтрейн"
    }]
}
 

Однако для модели identity в формате JSON API ответ должен выглядеть например:

 {
    "links": {
        "prev": "http://example.com/api/1.0/identities",
        "self": "http://example.com/api/1.0/identities?page=2",
        "следующий": "http: // пример.com / api / 1.0 / identity? page = 3 ",
    },
    "данные": [{
        "тип": "тождества",
        "id": "3",
        "attributes": {
            "имя пользователя": "Джон",
            "полное имя": "Джон Колтрейн"
        }
    }],
    "meta": {
        "pagination": {
          «count»: 20
        }
    }
}
 

Голы

В качестве JSON API Django REST Framework (сокращенно DJA) мы пытаемся достичь следующих целей:

  1. Поддержка спецификации JSON API в соответствии с

  2. Будьте максимально совместимы с Django REST Framework

    e.грамм. проблемы в Django REST Framework должны быть исправлены в апстриме, а не в DJA

  3. Иметь разумные настройки по умолчанию, чтобы их было как можно легче подобрать

  4. Будьте надежны и протестированы с хорошим покрытием

  5. Будьте работоспособны

Требования

  1. Python (3,6, 3,7, 3,8, 3,9)
  2. Джанго (2.2, 3.0, 3.1)
  3. Фреймворк Django REST (3.12)

Мы, , настоятельно рекомендуем и официально поддерживаем только последний выпуск исправлений для каждой серии Python, Django и REST Framework.

Обычно серии Python и Django поддерживаются до официального окончания срока службы. Для Django REST Framework поддерживаются две последние серии.

Установка

из PyPI

 $ pip установить djangorestframework-jsonapi
$ # для необязательной интеграции пакетов
$ pip install djangorestframework-jsonapi ['django-filter']
$ pip install djangorestframework-jsonapi ['django-polymorphic']
$ pip install djangorestframework-jsonapi ['openapi']
 

Из источника

 $ git clone https: // github.com / django-json-api / django-rest-framework-json-api.git
$ cd django-rest-framework-json-api
$ pip install -e.
 

Запуск примера приложения

Рекомендуется создать виртуальный сервер для тестирования. Предполагая, что это уже установлено и активировано:

 $ git clone https://github.com/django-json-api/django-rest-framework-json-api.git
$ cd django-rest-framework-json-api
$ pip install -Ur requirements.txt
$ django-admin migrate --settings = example.settings
$ django-admin loaddata drf_example --settings = example.настройки
$ django-admin runserver --settings = example.settings
 

Перейти к * http: // localhost: 8000 для списка доступных коллекций (в формате, отличном от JSONAPI!), * http: // localhost: 8000 / swagger-ui / для пользовательского интерфейса Swagger для просмотра динамической схемы или * http: // localhost: 8000 / openapi для документа спецификации OpenAPI представления схемы.

Использование

rest_framework_json_api предполагает, что вы используете представления на основе классов в Django. Остальные рамки.

Настройки

Можно добавить rest_framework_json_api.parsers.JSONParser и rest_framework_json_api.renderers.JSONRenderer для каждого класса ViewSet или изменить настройки . REST_FRAMEWORK

 REST_FRAMEWORK = {
    'PAGE_SIZE': 10,
    'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler',
    "DEFAULT_PAGINATION_CLASS":
        'rest_framework_json_api.pagination.JsonApiPageNumberPagination',
    'DEFAULT_PARSER_CLASSES': (
        'rest_framework_json_api.parsers.JSONParser',
        rest_framework.parsers.FormParser ',
        'rest_framework.parsers.MultiPartParser'
    ),
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework_json_api.renderers.JSONRenderer',
        'rest_framework_json_api.renderers.BrowsableAPIRenderer',
    ),
    'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',
    'DEFAULT_FILTER_BACKENDS': (
        'rest_framework_json_api.filters.QueryParameterValidationFilter',
        'rest_framework_json_api.filters.OrderingFilter',
        rest_framework_json_api.django_filters.DjangoFilterBackend ',
        'rest_framework.filters.SearchFilter',
    ),
    'SEARCH_PARAM': 'фильтр [поиск]',
    'TEST_REQUEST_RENDERER_CLASSES': (
        'rest_framework_json_api.renderers.JSONRenderer',
    ),
    'TEST_REQUEST_DEFAULT_FORMAT': 'vnd.api + json'
}
 

Этот пакет предоставляет гораздо больше, включая автоматическое изменение ключей JSON, дополнительные данные верхнего уровня (с использованием вложенных сериализаторы), отношения, ссылки, пагинаторы, фильтры и удобные ярлыки. Узнайте больше на http: // django-rest-framework-json-api.readthedocs.org/

Руководство по созданию конечной точки API с помощью Django Rest Framework

В рамках нашей работы по созданию четких веб-приложений в Caktus мы часто создаем конечные точки API, которые позволяют другому программному обеспечению взаимодействовать с сервером. Часто это означает использование внешнего интерфейса (React, Vue или Angular), хотя это также может означать подключение некоторого другого программного обеспечения для взаимодействия с сервером. Многие наши конечные точки API в разных проектах в конечном итоге работают одинаково, поэтому мы научились их писать, и в этом сообщении в блоге приведен пример того, как это сделать.

Типичный запрос конечной точки API может выглядеть примерно так: «внешнее приложение должно иметь возможность читать, создавать и обновлять компании через API». Вот краткое описание создания модели, сериализатора и представления для такого сценария, включая тесты для каждой части:

Часть 1: Модель

В этом примере мы предположим, что модель компании в настоящее время не существует в Django, поэтому мы создадим модель с некоторыми базовыми полями:

 # models.py
из моделей импорта django.db


класс Компания (models.Модель):
    name = models.CharField (max_length = 255)
    description = models.TextField (blank = True)
    website = models.URLField (blank = True)
    street_line_1 = models.CharField (max_length = 255)
    street_line_2 = models.CharField (max_length = 255, blank = True)
    city ​​= models.CharField (max_length = 80)
    состояние = models.CharField (max_length = 80)
    zipcode = models.CharField (max_length = 10)

    def __str __ (сам):
        вернуть self.name
 

Написание тестов важно для проверки правильности работы нашего приложения, поэтому мы добавляем тест для метода __str __ ().Примечание: мы используем библиотеки factory-boy и Faker для создания тестовых данных:

 # tests / factoryies.py
с фабрики импортировать DjangoModelFactory, Faker

от ..models import Company


класс CompanyFactory (DjangoModelFactory):
    name = Faker ('компания')
    description = Faker ('текст')
    website = Faker ('url')
    street_line_1 = Faker ('street_address')
    city ​​= Faker ('город')
    состояние = Faker ('state_abbr')
    zipcode = Faker ('почтовый индекс')

    класс Мета:
        model = Компания
 
 # тесты / test_models.ру
из django.test импортировать TestCase

от ..models import Company
из .factories import CompanyFactory


класс CompanyTestCase (TestCase):
    def test_str (сам):
        "" "Проверка строкового представления." ""
        company = CompanyFactory ()
        self.assertEqual (str (компания), company.name)
 

Создав модель, мы можем перейти к созданию сериализатора для обработки данных, входящих и исходящих из нашего приложения для модели компании.

Часть 2: Сериализатор

Django Rest Framework использует сериализаторы для обработки преобразования данных между JSON или XML и собственными объектами Python.Мы можем импортировать ряд полезных сериализаторов, которые упростят сериализацию наших объектов. Наиболее распространенным из них является ModelSerializer, который удобно использовать для сериализации данных для объектов Company:

 # serializers.py
from rest_framework.serializers import ModelSerializer

от компании .models import

класс CompanySerializer (ModelSerializer):
    класс Мета:
        model = Компания
        поля = (
            id, name, description, website, street_line_1, street_line_2,
            'Город (*): Штат (*): Почтовый Индекс'
        )
 

Это все, что требуется для определения сериализатора, хотя можно добавить гораздо больше настроек, например:

  • выводит поля, которых нет в модели (может быть, что-то вроде is_new_company или другие данные, которые можно вычислить на бэкэнде)
  • настраиваемая логика проверки, когда данные отправляются в конечную точку для любого из полей
  • настраиваемая логика для создания (запросы POST) или обновлений (запросы PUT или PATCH)

Также полезно добавить простой тест для нашего сериализатора, убедившись, что значения для каждого из полей в сериализаторе соответствуют значениям для каждого из полей в модели:

 # тесты / test_serializers.ру
из django.test импортировать TestCase

from ..serializers import CompanySerializer
из .factories import CompanyFactory


класс CompanySerializer (TestCase):
    def test_model_fields (самостоятельно):
        "" "Данные сериализатора соответствуют объекту Company для каждого поля." ""
        company = CompanyFactory ()
        для field_name в [
            id, name, description, website, street_line_1, street_line_2,
            'Город (*): Штат (*): Почтовый Индекс'
        ]:
            self.assertEqual (
                сериализатор.данные [field_name],
                getattr (компания, имя_поля)
            )
 

Часть 3: Просмотр

Представление — это уровень, на котором мы подключаем URL-адрес к набору запросов и сериализатор для каждого объекта в наборе запросов. Django Rest Framework снова предоставляет полезные объекты, которые мы можем использовать для определения нашего представления. Поскольку мы хотим создать конечную точку API для чтения, создания и обновления объектов Company, мы можем использовать миксины Django Rest Framework для таких действий. Django Rest Framework предоставляет ModelViewSet, который по умолчанию позволяет обрабатывать запросы POST, PUT, PATCH и DELETE, но поскольку нам не нужно обрабатывать запросы DELETE, мы можем использовать соответствующие миксины для каждого из необходимых нам действий:

 # просмотров.ру
из rest_framework.mixins import (
    CreateModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
)
из rest_framework.viewsets import GenericViewSet

от компании .models import
из .serializers импортировать CompanySerializer


class CompanyViewSet (GenericViewSet, # общие функции просмотра
                     CreateModelMixin, # обрабатывает POST
                     RetrieveModelMixin, # обрабатывает GET для 1 компании
                     UpdateModelMixin, # обрабатывает PUT и PATCH
                     ListModelMixin): # обрабатывает GET для многих компаний

      serializer_class = CompanySerializer
      queryset = Компания.', включить (router.urls)),
]
 

Теперь у нас есть конечная точка API, которая позволяет делать запросы GET, POST, PUT и PATCH для чтения, создания и обновления объектов Company. Чтобы убедиться, что он работает так, как мы ожидаем, мы добавляем несколько тестов:

 # tests / test_views.py
из django.test импортировать TestCase
из django.urls импортировать обратный
из статуса импорта rest_framework

из .factories импортировать CompanyFactory, UserFactory


класс CompanyViewSetTestCase (TestCase):
      def setUp (сам):
          себя.user = UserFactory (email='[email protected] ')
          self.user.set_password ('testpassword')
          self.user.save ()
          self.client.login (электронная почта = self.user.email, пароль = 'testpassword')
          self.list_url = reverse ('список-компаний')

      def get_detail_url (self, company_id):
          вернуть обратный (self.company-detail, kwargs = {'id': company_id})

      def test_get_list (сам):
          "" "ПОЛУЧИТЬ страницу со списком компаний." ""
          компании = [CompanyFactory () для i в диапазоне (0, 3)]

          ответ = себя.client.get (self.list_url)

          self.assertEqual (response.status_code, status.HTTP_200_OK)
          self.assertEqual (
              set (company ['id'] для компании в response.data ['results']),
              набор (company.id для компании в компаниях)
          )

      def test_get_detail (сам):
          "" "ПОЛУЧИТЕ страницу сведений о компании." ""
          company = CompanyFactory ()
          response = self.client.get (self.get_detail_url (company.id))
          self.assertEqual (response.status_code, статус.HTTP_200_OK)
          self.assertEqual (response.data ['имя'], company.name)

      def test_post (сам):
          "" "POST для создания компании." ""
          data = {
              'name': 'Новое имя',
              'description': 'Новое описание',
              'street_line_1': 'Новая street_line_1',
              'city': 'Новый город',
              'состояние': 'Нью-Йорк',
              'zipcode': '12345',
          }
          self.assertEqual (Company.objects.count (), 0)
          response = self.client.post (self.list_url, data = данные)
          self.assertEqual (response.status_code, status.HTTP_201_CREATED)
          self.assertEqual (Company.objects.count (), 1)
          company = Company.objects.all (). first ()
          для field_name в data.keys ():
                self.assertEqual (getattr (компания, имя_поля), данные [имя_поля])

      def test_put (сам):
          "" "PUT, чтобы обновить компанию." ""
          company = CompanyFactory ()
          data = {
              'name': 'Новое имя',
              'description': 'Новое описание',
              'street_line_1': 'Новая street_line_1',
              'city': 'Новый город',
              'состояние': 'Нью-Йорк',
              'zipcode': '12345',
          }
          ответ = себя.client.put (
              self.get_detail_url (company.id),
              данные = данные
          )
          self.assertEqual (response.status_code, status.HTTP_200_OK)

          # Объект действительно обновлен
          company.refresh_from_db ()
          для field_name в data.keys ():
              self.assertEqual (getattr (компания, имя_поля), данные [имя_поля])

      def test_patch (сам):
          "" "ПАТЧ для обновления компании." ""
          company = CompanyFactory ()
          data = {'name': 'Новое имя'}
          ответ = себя.client.patch (
              self.get_detail_url (company.id),
              данные = данные
          )
          self.assertEqual (response.status_code, status.HTTP_200_OK)

          # Объект действительно обновлен
          company.refresh_from_db ()
          self.assertEqual (имя компании, данные ['имя'])

      def test_delete (сам):
          "" "УДАЛЕНИЕ не реализовано." ""
          company = CompanyFactory ()
          response = self.client.delete (self.get_detail_url (company.id))
          себя.assertEqual (response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
 

По мере того, как приложение становится более сложным, мы добавляем больше функций (и больше тестов) для обработки таких вещей, как разрешения и обязательные поля. Чтобы быстро ограничить разрешения для аутентифицированных пользователей, мы добавляем в наш файл настроек следующее:

 # файл настроек
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',)
}
 

И добавьте тест, который только авторизованные пользователи могут получить доступ к конечной точке:

 # tests / test_views.ру
из django.test импортировать TestCase
из django.urls импортировать обратный
из статуса импорта rest_framework

из .factories импортировать CompanyFactory, UserFactory


класс CompanyViewSetTestCase (TestCase):

      ...

      def test_unauthenticated (сам):
          "" "Пользователи, не прошедшие аутентификацию, не могут использовать API." ""
          self.client.logout ()
          company = CompanyFactory ()

          с self.subTest ('ПОЛУЧИТЬ страницу списка'):
              response = self.client.get (self.list_url)
              self.assertEqual (ответ.status_code, status.HTTP_403_FORBIDDEN)

          с self.subTest ('Получить страницу сведений'):
              response = self.client.get (self.get_detail_url (company.id))
              self.assertEqual (response.status_code, status.HTTP_403_FORBIDDEN)

          с self.subTest ('PUT'):
              data = {
                  'name': 'Новое имя',
                  'description': 'Новое описание',
                  'street_line_1': 'Новая street_line_1',
                  'city': 'Новый город',
                  'состояние': 'Нью-Йорк',
                  'zipcode': '12345',
              }
              ответ = себя.client.put (self.get_detail_url (company.id), data = data)
              self.assertEqual (response.status_code, status.HTTP_403_FORBIDDEN)
              # Компания не обновлялась
              company.refresh_from_db ()
              self.assertNotEqual (имя компании, данные ['имя'])

          с self.subTest ('PATCH):
              data = {'name': 'Новое имя'}
              response = self.client.patch (self.get_detail_url (company.id), data = data)
              self.assertEqual (response.status_code, статус.HTTP_403_FORBIDDEN)
              # Компания не обновлялась
              company.refresh_from_db ()
              self.assertNotEqual (имя компании, данные ['имя'])

          с помощью self.subTest ('POST'):
              data = {
                  'name': 'Новое имя',
                  'description': 'Новое описание',
                  'street_line_1': 'Новая street_line_1',
                  'city': 'Новый город',
                  'состояние': 'Нью-Йорк',
                  'zipcode': '12345',
              }
              ответ = себя.client.put (self.list_url, данные = данные)
              self.assertEqual (response.status_code, status.HTTP_403_FORBIDDEN)

      с self.subTest ('УДАЛИТЬ'):
              response = self.client.delete (self.get_detail_url (company.id))
              self.assertEqual (response.
        
	

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Theme: Overlay by Kaira Extra Text
Cape Town, South Africa