Когда истекает пагинация Django REST Framework CURSOR? - PullRequest
0 голосов
/ 13 мая 2019

При использовании пагинации CURSOR в Django REST Framework, он использует cursor параметр запроса, такой как ?cursor=xxxxxxx (может быть, это идентификатор курсора базы данных?), И я предполагаю, что срок действия курсора истечет через некоторое время, чтобы он пришел к быть недоступным больше.

Мое предположение верно? если да, то когда он истек?

1 Ответ

1 голос
/ 13 мая 2019

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

Давайте рассмотрим его на примере:

models.py

class BlogPost(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    content = models.TextField()

    created = models.DateTimeField(auto_now_add=True, unique=True)

serializers.py

class BlogPostListSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ['title', 'description', 'created']

views.py

class BlogPostCursorPagination(CursorPagination):
    page_size = 5
    ordering = '-created'

class BlogPostListView(ListAPIView):
    queryset = BlogPost.objects.all().order_by('-created')
    serializer_class = BlogPostListSerializer
    pagination_class = BlogPostCursorPagination

Результаты:

GET /posts/
{
    "next": "http://127.0.0.1:8000/posts/?cursor=cD0yMDE5LTA1LTEzKzE1JTNBNTYlM0EzNy4xMjI4NjUlMkIwMCUzQTAw",
    "previous": null,
    "results": [
        {
            "title": "Latest post",
            "description": "This is the latest post",
            "created": "2019-05-13T15:57:08.574475Z"
        },
        {
            "title": "Previous post",
            "description": "This post was created before the latest one",
            "created": "2019-05-13T15:57:00.971509Z"
        },
        {
            "title": "2nd previoust post",
            "description": "This one was created even before",
            "created": "2019-05-13T15:56:53.053740Z"
        },
        {
            "title": "3rd previous post",
            "description": "And so on...",
            "created": "2019-05-13T15:56:43.804315Z"
        },
        {
            "title": "4rd previous post",
            "description": "And so on...",
            "created": "2019-05-13T15:56:37.122865Z"
        }
    ]
}

Как видите, есть некоторая «фигня», заданная каккурсор в следующей ссылке.Это не просто мусор, это закодированное в base64 значение поля created последнего элемента на текущей странице.Вот и все ...

Если вы нажмете на эту ссылку, django-rest-framework расшифрует ее и отобразит для вас 5 элементов ПОСЛЕ этого, не включая себя.Это так же просто, как:

BlogPost.objects.filter(created__lt=datetime(2019, 5, 13, 15, 56, 37, 122865, tzinfo=utc))

Обратите внимание, что мы используем __lt, потому что порядок элементов обратный: сначала появляются новейшие записи.

Так что, если вы измените этот курсори замените DateTime внутри на DateTime 2-го сообщения из списка, вы получите сообщения от 3 до 7:

GET /posts/?cursor=cD0yMDE5LTA1LTEzKzE1JTNBNTclM0EwMC45NzE1MDklMkIwMCUzQTAw
{
    "next": null,
    "previous": "http://127.0.0.1:8000/posts/?cursor=cj0xJnA9MjAxOS0wNS0xMysxNSUzQTU2JTNBNTMuMDUzNzQwJTJCMDAlM0EwMA%3D%3D",
    "results": [
        {
            "title": "2nd previoust post",
            "description": "This one was created even before",
            "created": "2019-05-13T15:56:53.053740Z"
        },
        {
            "title": "3rd previous post",
            "description": "And so on...",
            "created": "2019-05-13T15:56:43.804315Z"
        },
        {
            "title": "4rd previous post",
            "description": "And so on...",
            "created": "2019-05-13T15:56:37.122865Z"
        },
        {
            "title": "5rd previous post",
            "description": "And so on...",
            "created": "2019-05-13T15:56:29.501963Z"
        },
        {
            "title": "6rd previous post",
            "description": "And so on...",
            "created": "2019-05-13T15:56:22.033332Z"
        }
    ]
}

Также нет проверки, если объект, на который указывает курсор, существует в базе данных.,Если вы попытаетесь установить метку времени после 2-го сообщения, вы получите сообщения от 2 до 6:

GET /posts/?cursor=cD0yMDE5LTA1LTEzKzE1JTNBNTclM0EwMC45NzE1MTAlMkIwMCUzQTAw
{
    "next": "http://127.0.0.1:8000/posts/?cursor=cD0yMDE5LTA1LTEzKzE1JTNBNTYlM0EyOS41MDE5NjMlMkIwMCUzQTAw",
    "previous": "http://127.0.0.1:8000/posts/?cursor=cj0xJnA9MjAxOS0wNS0xMysxNSUzQTU3JTNBMDAuOTcxNTA5JTJCMDAlM0EwMA%3D%3D",
    "results": [
        {
            "title": "Previous post",
            "description": "This post was created before the latest one",
            "created": "2019-05-13T15:57:00.971509Z"
        },
        {
            "title": "2nd previoust post",
            "description": "This one was created even before",
            "created": "2019-05-13T15:56:53.053740Z"
        },
        {
            "title": "3rd previous post",
            "description": "And so on...",
            "created": "2019-05-13T15:56:43.804315Z"
        },
        {
            "title": "4rd previous post",
            "description": "And so on...",
            "created": "2019-05-13T15:56:37.122865Z"
        },
        {
            "title": "5rd previous post",
            "description": "And so on...",
            "created": "2019-05-13T15:56:29.501963Z"
        }
    ]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...