Рубрики
Без рубрики

Структура Django Rest Laste Lake Easy Cantage

При создании любого применения необходимость привлечения небольшого подмножества большого результата, полученного от … с меткой Django, Python.

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

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

Таким образом, страдание является основной для любого приложения, но есть несколько способов реализовать ее с использованием django. Вы можете пойти с классом PAGINATOR, который выходит из коробки, если все, что вам нужно, это минимум, но если вы ищете более богатое функционирование решения, то Framework Django Rest – это то, что нужно.

Как должна работать страниц

Любой тип страниц может быть реализован путем выполнения простой шаблона ответа API. API должен вернуть эти 4 детали.

  1. Подсчет количества записей в полном наборе результатов.
  2. Список записей, которые представляют одну страницу набора результатов.
  3. URL, который можно использовать для получения следующей страницы, если существует следующая страница.
  4. URL, который можно использовать для получения предыдущей страницы, если существует предыдущая страница.

Ранее я продемонстрировал Как приложения CRUD можно построить с помощью DRF С яблочными заметками, такими как приложение в качестве ссылки, и я считаю, что один и тот же пример можно использовать для демонстрации страниц.

Допустим, в базе данных есть 10 заметок, но я хочу смотреть только на последние 2 ноты за раз, ответ API для API списка заметок должен выглядеть так

{    
    "count": 10,
    "next": "http://localhost:8000/note/all?p=2",
    "previous": null,
    "results": [
        {
            "id": 10,
            "title": "Note 10",
            "content": "content 10",
            "last_udpated_on": "2021-01-09T01:44:33.645706Z",
            "is_active": true,
            "created": "2021-01-09T01:44:33.645745Z"
        },
        {
            "id": 9,
            "title": "Note 9",
            "content": "content 9",
            "last_udpated_on": "2021-01-09T01:44:29.487257Z",
            "is_active": true,
            "created": "2021-01-09T01:44:29.487295Z"
        }
    ]
}

Это может быть достигнуто с помощью DRF с 2 строками кода.

Пэгинг ответа API

Самый быстрый способ – настройка страниц на глобальном масштабе и применить его на все API, где набор запросов возвращается в качестве ответа.

Сначала убедитесь, что в вашем приложении установлена структура Django REST, а затем добавьте эти строки кода в настройки.py

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

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

Переопределение страниц для каждого представления API

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

Затем вы можете включить Pagination_class в Ваш вид API, как показано ниже.

from django.shortcuts import render, get_object_or_404

from rest_framework.viewsets import ModelViewSet
from .models import Note
from .serializers import NoteSerializer
from .paginations import CustomPagination
# Create your views here.


class NoteViewSet(ModelViewSet):
    serializer_class = NoteSerializer
    pagination_class = CustomPagination

    def get_object(self):
        return get_object_or_404(Note, id=self.request.query_params.get("id"))

    def get_queryset(self):
        return Note.objects.filter(is_active=True).order_by('-last_udpated_on')

    def perform_destroy(self, instance):
        instance.is_active = False
        instance.save()

Чтобы создать пользовательский класс страниц, сначала создайте файл paginations.py в папке вашего приложения и создайте класс, который наследует от существующего пагинатора DRF.

from rest_framework import pagination

class CustomPagination(pagination.PageNumberPagination):
    page_size = 2
    page_size_query_param = 'page_size'
    max_page_size = 50
    page_query_param = 'p'

Параметры, приведенные в этом пользовательском классе Paginator, позволят вам предоставить page_size Параметр запроса, чтобы определить размер каждой страницы. Если этот параметр существует, он будет переопределять размер страницы по умолчанию 2. Сам номер страницы будет указан с использованием параметра запроса p.

Поэтому называть URL http://localhost: 8000/note/all? p = 2 & page_size = 3 теперь приведет к этому ответу:

{
    "count": 10,
    "next": "http://localhost:8000/note/all?p=3&page_size=3",
    "previous": "http://localhost:8000/note/all?page_size=3",
    "results": [
        {
            "id": 7,
            "title": "Note 7",
            "content": "content 7",
            "last_udpated_on": "2021-01-09T01:44:21.560544Z",
            "is_active": true,
            "created": "2021-01-09T01:44:21.560582Z"
        },
        {
            "id": 6,
            "title": "Note 6",
            "content": "content 6",
            "last_udpated_on": "2021-01-09T01:44:17.883444Z",
            "is_active": true,
            "created": "2021-01-09T01:44:17.883483Z"
        },
        {
            "id": 5,
            "title": "Note 5",
            "content": "content 5",
            "last_udpated_on": "2021-01-09T01:44:13.344068Z",
            "is_active": true,
            "created": "2021-01-09T01:44:13.344107Z"
        }
    ]
}

Это из-за установки размера страницы 3 и извлечения второй страницы в наборе результатов.

Типы пневматических знаний, предлагаемые DRF

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

  • Номер страницы
  • Ограничение и смещение страниц
  • Курсорская страница

Номер страницы

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

Ограничение и смещение страниц

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

from rest_framework import pagination

class CustomPagination(pagination.LimitOffsetPagination):
    default_limit = 2
    limit_query_param = 'l'
    offset_query_param = 'o'
    max_limit = 50

Limit_query_param и offset_query_param укажет имена параметров запроса, которые будут использоваться для ограничения и смещения. Вы можете установить default_limit Если параметр запроса не предоставлен и max_limit Чтобы ограничить максимальное количество строк, возвращаемых на странице.

Если используется этот класс Paginator, ответ возвращается URL http://localhost: 8000/note/all? l = 3 & o = 3 было бы что -то подобное.

{
    "count": 10,
    "next": "http://localhost:8000/note/all?l=3&o=6",
    "previous": "http://localhost:8000/note/all?l=3",
    "results": [
        {
            "id": 7,
            "title": "Note 7",
            "content": "content 7",
            "last_udpated_on": "2021-01-09T01:44:21.560544Z",
            "is_active": true,
            "created": "2021-01-09T01:44:21.560582Z"
        },
        {
            "id": 6,
            "title": "Note 6",
            "content": "content 6",
            "last_udpated_on": "2021-01-09T01:44:17.883444Z",
            "is_active": true,
            "created": "2021-01-09T01:44:17.883483Z"
        },
        {
            "id": 5,
            "title": "Note 5",
            "content": "content 5",
            "last_udpated_on": "2021-01-09T01:44:13.344068Z",
            "is_active": true,
            "created": "2021-01-09T01:44:13.344107Z"
        }
    ]
}

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

Курсорская страница

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

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

Кроме того, эта страница не вернет подсчет запис, потому что на всем наборе результатов нет запроса.

from rest_framework import pagination
from rest_framework.response import Response
from collections import OrderedDict

class CustomPagination(pagination.CursorPagination):
    page_size = 2
    cursor_query_param = 'c'
    ordering = '-id'

custom_query_param Указывает, какой параметр запроса использовать для представления курсора и Заказ Указывает поле, основываясь на том, какое страницу будет применяться. Поскольку это поле должно иметь фиксированный порядок, а значения должны быть уникальными, я выбрал первичный ключ в спуска в качестве упорядочения.

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

{
    "next": "http://localhost:8000/note/all?c=cD05",
    "previous": null,
    "results": [
        {
            "id": 10,
            "title": "Note 10",
            "content": "content 10",
            "last_udpated_on": "2021-01-09T01:44:33.645706Z",
            "is_active": true,
            "created": "2021-01-09T01:44:33.645745Z"
        },
        {
            "id": 9,
            "title": "Note 9",
            "content": "content 9",
            "last_udpated_on": "2021-01-09T01:44:29.487257Z",
            "is_active": true,
            "created": "2021-01-09T01:44:29.487295Z"
        }
    ]
}

Нажав на следующий URL -адрес

{
    "next": "http://localhost:8000/note/all?c=cD03",
    "previous": "http://localhost:8000/note/all?c=cj0xJnA9OA%3D%3D",
    "results": [
        {
            "id": 8,
            "title": "Note 8",
            "content": "content 8",
            "last_udpated_on": "2021-01-09T01:44:25.712231Z",
            "is_active": true,
            "created": "2021-01-09T01:44:25.712268Z"
        },
        {
            "id": 7,
            "title": "Note 7",
            "content": "content 7",
            "last_udpated_on": "2021-01-09T01:44:21.560544Z",
            "is_active": true,
            "created": "2021-01-09T01:44:21.560582Z"
        }
    ]
}

Пользовательская страница

Если вы предпочитаете иметь количество, предыдущая ссылка и следующая ссылка в заголовках HTTP, в то время как данные содержат только список результатов, вы можете сделать эти настройки, переопределив get_pagination_response Метод в классе страниц, который вы наследуете от любого из 3 вышеупомянутых типов становок.

from rest_framework import pagination
from rest_framework.response import Response
from collections import OrderedDict

class CustomPagination(pagination.PageNumberPagination):
    page_size = 2
    page_size_query_param = 'page_size'
    max_page_size = 50
    page_query_param = 'p'

    def get_paginated_response(self, data):
        response = Response(data)
        response['count'] = self.page.paginator.count
        response['next'] = self.get_next_link()
        response['previous'] = self.get_previous_link()
        return response

Теперь вы увидите ссылки в заголовках и только фактические данные в ответе

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
count: 10
next: http://localhost:8000/note/all?p=2
previous: None

[
{
"id": 10,
"title": "Note 10",
"content": "content 10",
"last_udpated_on": "2021-01-09T01:44:33.645706Z",
"is_active": true,
"created": "2021-01-09T01:44:33.645745Z"
},
{
"id": 9,
"title": "Note 9",
"content": "content 9",
"last_udpated_on": "2021-01-09T01:44:29.487257Z",
"is_active": true,
"created": "2021-01-09T01:44:29.487295Z"
}
]

Заключительные заметки

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

Сам DRF наследуется от класса PAGINATOR по умолчанию, чтобы вы могли сохранить себя некоторое время. Первоначально опубликовано в моем блоге

Оригинал: “https://dev.to/sankalpjonna/pagination-made-easy-with-django-rest-framework-504f”