Основы Django REST Framework

Эта статья служит введением в Фреймворк Django REST, уделяя особое внимание следующим основным концепциям:

  1. Сериализаторы
  2. Виды и наборы представлений
  3. Маршрутизаторы
  4. Аутентификация и авторизация

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

Фреймворк Django REST

Django REST Framework (DRF) - это широко используемый полнофункциональный API-фреймворк, предназначенный для создания RESTful API с помощью Django. По своей сути DRF интегрируется с основными функциями Django - моделями, представлениями и URL-адресами, что упрощает создание RESTful API.

Хотите узнать больше о RESTful API? Ознакомьтесь с Что такое RESTful API?.

DRF состоит из следующих компонентов:

  1. Сериализаторы используются для преобразования наборов запросов Django и экземпляров моделей в (сериализация) и из (десериализация) JSON (и ряда других форматов отображения данных, таких как XML и YAML).
  2. Представления (наряду с наборами представлений), которые аналогичны традиционным представлениям Django, обрабатывают HTTP-запросы и ответы RESTful. Само представление использует сериализаторы для проверки входящих полезных данных и содержит необходимую логику для возврата ответа. Наборы представлений связаны с маршрутизаторами, которые сопоставляют представления с доступными URL-адресами.

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

Что такое сериализатор?

Что такое сериализатор в Django REST Framework?

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

Почему данные должны быть (де)сериализованы?

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

Помните: RESTful API предназначены для использования другими компьютерами, поэтому взаимодействие должно быть унифицированным и универсальным. Что такое RESTful API?в рассказывается обо всем этом и многом другом. Обязательно ознакомьтесь с этим!

Краткие примеры

Чтобы указать способ сериализации и десериализации входящих и исходящих данных, вы создаете класс [SomeResource]Serializer. Итак, если у вас есть модель Task, вы должны создать класс TaskSerializer.

Например:

# model
class Task(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()
    completed = models.BooleanField(default=False)


# basic serializer
class TaskSerializer(serializers.Serializer):
    title = serializers.CharField()
    description = serializers.CharField()
    completed = serializers.BooleanField()

Аналогично тому, как создаются формы Django, когда сериализация тесно связана с моделью, вы можете расширить ModelSerializer:

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = "__all__"

Вы можете легко адаптировать ModelSerializer к вашим потребностям:

class TaskSerializer(serializers.ModelSerializer):
    short_description = serializers.SerializerMethodField()

    class Meta:
        model = Task
        fields = ["title", "description", "completed", "short_description"]
        read_only_fields = ['completed']

    def get_short_description(self, obj):
        return obj.description[:50]

Здесь мы-

  1. Явно определены поля, к которым сериализатор имеет доступ с помощью атрибута fields
  2. Установите для поля completed значение read-only
  3. Добавлены дополнительные данные -- short_description

DRF также позволяет создавать API, управляемый гипертекстом:

class TaskSerializer(serializers.HyperlinkedModelSerializer):
    subtasks = serializers.HyperlinkedRelatedField(
        many=True,
        read_only=True,
        view_name='subtask-detail'
    )

    class Meta:
        model = Task
        fields = ['name', 'subtasks']

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

Ресурсы

Вы можете узнать больше о сериализаторах из официальной документации:

  1. Документация по сериализаторам, Поля сериализатора и Отношения сериализатора.
  2. Официальное руководство по Сериализации и по API с гиперссылками.

Если вас интересует общая структура документации DRF, обратитесь к Документации DRF.

Для получения более подробного материала ознакомьтесь со следующими ресурсами:

  1. Эффективное использование сериализаторов фреймворка Django REST
  2. Зачем мне нужен сериализатор?
  3. Улучшите производительность сериализации в Django Rest Framework
  4. Пользовательские проверки для полей сериализатора Django Rest Framework
  5. Как сохранить дополнительные данные в сериализаторе Django REST Framework
  6. Определение различных сериализаторов для ввода и вывода информации.

Виды и наборы представлений

Что такое виды и наборы представлений?

Что такое представления фреймворка Django REST и чем они отличаются от представлений Django?

Просмотры фреймворка Django REST:

  1. Преобразовать входящие запросы в Запросы экземпляры
  2. Обрабатывать аутентификацию и авторизацию
  3. Выполнить какое-либо действие (создать, прочитать, обновить, удалить)
  4. Возвращает Ответ объект

В то время как представления Django обычно содержат HTML-шаблоны, представления DRF возвращают ответ в формате JSON.

DRF имеет три различных типа представлений:

  1. APIView
  2. Общий вид
  3. Набор представлений

Все представления DRF основаны на базовом классе APIView (который основан на классе View в Django). Хотя DRF поддерживает представления, основанные на функциях, обычно они основаны на классах (CBV).

В чем разница между представлениями DRF и наборами представлений?

Наборы представлений позволяют объединять связанные представления в один класс.

Вместо обработчиков методов, таких как .get() и .post(), наборы представлений предоставляют действия, такие как .list() и .create().

Преимущество использования ViewSet перед view заключается в том, что они сводят к минимуму объем кода, который вам нужно написать, и обеспечивают согласованность ваших URL-адресов. Имейте в виду, что ViewSet могут сделать ваш код менее читабельным, поскольку в нем довольно много всего происходит под капотом.

Краткие примеры

Просмотр приложений

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

Простое представление на основе классов:

class ListTasks(APIView):
    def get(self, request):
        tasks = Task.objects.all()
        serializer = TaskSerializer(tasks, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = TaskSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Та же функциональность может быть достигнута с помощью функционального представления, подобного следующему:

@api_view(['GET', 'POST'])
def list_tasks(request):
    if request.method == 'GET':
        tasks = Task.objects.all()
        serializer = TaskSerializer(tasks, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = TaskSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Общий вид

Универсальные представления предназначены для обработки распространенных вариантов использования без особых проблем. Например, для обработки приведенного выше варианта использования следует использовать ListCreateAPIView:

class RetrieveUpdateDeleteTask(ListCreateAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer

Набор представлений

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

class TaskViewSet(viewsets.ViewSet):
    def list(self, request):
        queryset = Task.objects.all()
        serializer = TaskSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        queryset = Task.objects.all()
        user = get_object_or_404(queryset, pk=pk)
        serializer = TaskSerializer(user)
        return Response(serializer.data)

Обратите внимание, что один URL-адрес (не включающий pk) потребуется для действия со списком, а другой (включающий pk) - для действия с извлечением.

Мы можем достичь того же результата, используя ReadOnlyModelViewSet:

class TaskModelViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = TaskSerializer
    queryset = Task.objects.all()

Чтобы охватить все возможные действия (создание, чтение, обновление, удаление), вы можете использовать ModelViewSet вместо ReadOnlyModelViewSet:

class TaskModelViewSet(viewsets.ModelViewSet):
    serializer_class = TaskSerializer
    queryset = Task.objects.all()

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

Ресурсы

Вы можете найти информацию о представлениях как в руководстве по API, так и в официальном руководстве по DRF:

  1. Документация и Руководство по представлениям, основанным на функциях.
  2. Документация и Учебное пособие для представлений на основе классов. Общие CBVS есть отдельная страница.
  3. Документация и Руководство по наборам представлений.

Для получения более подробного материала ознакомьтесь со следующими ресурсами:

  1. Серия просмотров DRF
  2. Ручное тестирование ModelViewSet с помощью Postman
  3. Атрибуты и методы ModelViewSet
  4. Как отключить метод в обсуждении набора представлений
  5. Как использовать разные сериализаторы в одном и том же обсуждении ModelViewSet

Маршрутизаторы

Что такое маршрутизатор в фреймворке Django REST?

В отличие от представлений DRF, для которых требуется аналогичный URLconf, к которому вы привыкли в представлениях Django, для наборов представлений DRF требуется несколько URL-адресов. Хотя технически этого можно достичь с помощью обычных urlpatterns, лучше всего использовать маршрутизаторы. Маршрутизаторы автоматически генерируют стандартные шаблоны URL-адресов и связывают их с заданным набором представлений.

DRF поставляется с двумя готовыми маршрутизаторами: SimpleRouter и DefaultRouter.

Краткие примеры

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

router = routers.DefaultRouter()
router.register(r'tasks', TaskViewSet)
router.register(r'work-hours', WorkHoursViewSet)


urlpatterns = [
    path('', include(router.urls)),
]

Ресурсы

  1. Документация
  2. Официальное руководство
  3. Обработка URL-адресов

Аутентификация и авторизация

Аутентификация против авторизации?

Что такое аутентификация и авторизация?

Аутентификация и авторизация совместно определяют, следует ли предоставлять доступ запросу к конечной точке:

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

Что такое аутентификация?

Аутентификация - это процесс проверки личности пользователя, выполняющего запрос, и он никоим образом не ограничивает доступ к API. Аутентификация может выполняться с использованием имени пользователя и пароля, токенов или сеансов. DRF также поддерживает удаленную аутентификацию пользователя.

Что такое авторизация?

В DRF авторизация состоит из двух частей: регулирования и разрешений:

  1. Регулирование регулирует частоту запросов, которые клиенты могут отправлять в API. После превышения скорости для каждого пользователя запрос будет (временно) отклонен.
  2. В отличие от регулирования, которое указывает на временное состояние, разрешения указывают на постоянное. Разрешения могут управлять глобальным доступом (например, только для прошедших проверку подлинности пользователей), доступом к конечной точке (например, только для администраторов) или даже доступом к отдельному объекту (например, только для создателя).

Краткие примеры

Аутентификацию, разрешения и регулирование можно настроить как глобально, так и для каждого вида.

Например, вы можете настроить все три параметра глобально следующим образом в вашем файле настроек Django:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'shopping_list.api.throttling.UserRateThrottle',
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/hour',
        'user': '1000/hour',
    },
}

В этом примере пользователь аутентифицируется с помощью токена, и только аутентифицированные пользователи получают доступ к API. Анонимные запросы ограничиваются после 10-го запроса за час, в то время как аутентифицированным пользователям разрешено выполнять 1000 запросов в час.

Настройка аутентификации, разрешений и регулирования для каждого вида выглядит следующим образом:

class TaskDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer

    authentication_classes = [TokenAuthentication]
    throttle_classes = [UserRateThrottle, AnonRateThrottle]
    permission_classes = [IsAuthenticated]

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

Ресурсы

Вы можете узнать больше об аутентификации и авторизации в официальных документах:

  1. Документация по проверке подлинности, Разрешения и Регулирование.
  2. Учебное пособие по аутентификации и разрешениям.

Для получения более подробного материала ознакомьтесь со следующими ресурсами:

  1. Разрешения в серии фреймворков Django REST
  2. Статья о проверке подлинности одностраничных приложений на основе сеанса Django
  3. Авторизация DRF с помощью Auth0
  4. Наконец-то разобрались с аутентификацией в Django REST Framework (видео)
  5. Аутентификация токенами фреймворка Django Rest Framework (видео)

Заключение

В этой статье рассмотрены основы фреймворка Django REST. Теперь у вас должно быть общее представление о том, как основные концепции - сериализаторы, представления и ViewSets, маршрутизаторы, аутентификация и авторизация - могут быть использованы для создания RESTful API. Если вы заинтригованы какой-либо из этих тем, я рекомендую вам ознакомиться с официальной документацией, а также с любыми дополнительными ресурсами, упомянутыми выше.

Если вы хотите узнать, как создавать API с помощью Django REST Framework, ознакомьтесь с нашим курсом Разработка RESTful API с помощью Django REST Framework. Курс знакомит вас с реальным циклом разработки приложения, попутно расширяя ваши знания о DRF с нуля. Если вы уже знакомы с DRF и хотите узнать больше, вы можете ознакомиться с Разработкой на основе тестирования с использованием Django, Django REST Framework и Docker, в которых основное внимание уделяется не столько функциям DRF, сколько тому, как реализовать ваш API в реальной жизни. мир.

Вернуться на верх