Django-rest-framework: CursorPagination рдХреЗ рд▓рд┐рдП IndexError рдЬрдм рдХреНрд╡реЗрд░реАрд╕реЗрдЯ рдмрджрд▓рддрд╛ рд╣реИ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 11 рдорд╛рд░реНрдЪ 2019  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: encode/django-rest-framework

рдЬрд╛рдВрдЪ рд╕реВрдЪреА

  • [X] рдореИрдВрдиреЗ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рдорд╕реНрдпрд╛ Django REST рдврд╛рдВрдЪреЗ рдХреА master рд╢рд╛рдЦрд╛ рдХреЗ рд╡рд┐рд░реБрджреНрдз рдореМрдЬреВрдж рд╣реИред
  • [x] рдореИрдВрдиреЗ рдЦреБрд▓реЗ рдФрд░ рдмрдВрдж рджреЛрдиреЛрдВ рдЯрд┐рдХрдЯреЛрдВ рдореЗрдВ рд╕рдорд╛рди рдореБрджреНрджреЛрдВ рдХреА рдЦреЛрдЬ рдХреА рд╣реИ рдФрд░ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдирд╣реАрдВ рдорд┐рд▓ рд░рд╣рд╛ рд╣реИред
  • [x] рдпрд╣ рдЙрдкрдпреЛрдЧ рдХрд╛ рдкреНрд░рд╢реНрди рдирд╣реАрдВ рд╣реИред (рдЙрдиреНрд╣реЗрдВ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдЪрд░реНрдЪрд╛ рд╕рдореВрд╣ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред)
  • [x] рдЗрд╕реЗ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд░реВрдк рдореЗрдВ рдирд╣реАрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред (рдЬрд╣рд╛рдВ рд╕рдВрднрд╡ рд╣реЛ, рд╣рдо рддреГрддреАрдп рдкрдХреНрд╖ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдирдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рджреЗрддреЗ рд╣реИрдВред)
  • [x] рдореИрдВрдиреЗ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╕рд░рд▓рддрдо рд╕рдВрднрд╡ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрдо рдХрд░ рджрд┐рдпрд╛ рд╣реИред
  • [x] рдореИрдВрдиреЗ рдПрдХ рдЕрд╕рдлрд▓ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рд░реВрдк рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рд╣реИред (рдпрджрд┐ рдЖрдк рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде рд╣реИрдВ рддреЛ рднреА рд╣рдо рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред)

рдкреНрд░рдЬрдирди рдХреЗ рдЪрд░рдг

  1. рдХрд░реНрд╕рд░ рдкреЗрдЬрд┐рдиреЗрд╢рди рд╕рдХреНрд╖рдо рдХрд░реЗрдВ
  2. рдкрд░реНрдпрд╛рдкреНрдд рдЖрдЗрдЯрдо рдмрдирд╛рдПрдВ рдХрд┐ рдкреЗрдЬрд┐рдиреЗрд╢рди рд╣реЛ
  3. рдкреЗрдЬ 2 рдкрд░ рдЬрд╛рдПрдВ
  4. рдЦреЛрд▓ рдХреЗ рднреАрддрд░ рд╕рднреА рдЖрдЗрдЯрдо рд╣рдЯрд╛рдПрдВ
  5. рдкреГрд╖реНрда рддрд╛рдЬрд╝рд╛ рдХрд░реЗрдВ
  6. рддреНрд░реБрдЯрд┐ рджреЗрдЦреЗрдВ

рдЕрдкреЗрдХреНрд╖рд┐рддреН рд╡реНрдпрд╡рд╣рд╛рд░

рд╕рдЪ рдХрд╣реВрдВ рддреЛ рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ, рд╢рд╛рдпрдж рдПрдХ рдЦрд╛рд▓реА рдкреГрд╖реНрдаред

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╡реНрдпрд╡рд╣рд╛рд░

Traceback (most recent call last):
  File "/var/env/lib/python3.6/site-packages/django/contrib/staticfiles/handlers.py", line 65, in __call__
    return self.application(environ, start_response)
  File "/var/env/lib/python3.6/site-packages/django/core/handlers/wsgi.py", line 142, in __call__
    response = self.get_response(request)
  File "/var/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 78, in get_response
    response = self._middleware_chain(request)
  File "/var/env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 36, in inner
    response = response_for_exception(request, exc)
  File "/var/env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 90, in response_for_exception
    response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
  File "/var/env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 125, in handle_uncaught_exception
    return debug.technical_500_response(request, *exc_info)
  File "/var/env/lib/python3.6/site-packages/django_extensions/management/technical_response.py", line 37, in null_technical_500_response
    six.reraise(exc_type, exc_value, tb)
  File "/var/env/lib/python3.6/site-packages/six.py", line 692, in reraise
    raise value.with_traceback(tb)
  File "/var/env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/var/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/var/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 124, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/var/env/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/var/env/lib/python3.6/site-packages/rest_framework/viewsets.py", line 116, in view
    return self.dispatch(request, *args, **kwargs)
  File "/var/env/lib/python3.6/site-packages/rest_framework/views.py", line 495, in dispatch
    response = self.handle_exception(exc)
  File "/var/env/lib/python3.6/site-packages/rest_framework/views.py", line 455, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/var/env/lib/python3.6/site-packages/rest_framework/views.py", line 492, in dispatch
    response = handler(request, *args, **kwargs)
  File "/var/env/lib/python3.6/site-packages/rest_framework/mixins.py", line 45, in list
    return self.get_paginated_response(serializer.data)
  File "/var/env/lib/python3.6/site-packages/rest_framework/generics.py", line 180, in get_paginated_response
    return self.paginator.get_paginated_response(data)
  File "/var/env/lib/python3.6/site-packages/rest_framework/pagination.py", line 781, in get_paginated_response
    ('previous', self.get_previous_link()),
  File "/var/env/lib/python3.6/site-packages/rest_framework/pagination.py", line 643, in get_previous_link
    compare = self._get_position_from_instance(self.page[0], self.ordering)
IndexError: list index out of range

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдзрдиреНрдпрд╡рд╛рдж @ewjoachim рдФрд░ @tomchristie

рд╕рднреА 4 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореИрдВ рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдЗрд╕рдореЗрдВ рдЬрд╛ рд░рд╣рд╛ рд╣реВрдВред рдЕрдЧрд░ 15 рдЕрдкреНрд░реИрд▓ рддрдХ рдореЗрд░реА рдУрд░ рд╕реЗ рдХреЛрдИ рдЦрдмрд░ рдирд╣реАрдВ рдЖрддреА рд╣реИ, рддреЛ рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдореИрдВ рдЕрдм рдЗрд╕ рдкрд░ рдирд╣реАрдВ рд╣реВрдВред

рдЯрд┐рдХрдЯ рдХреЗ рд╕рдЯреАрдХ рдЪрд░рдгреЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреЗ рд╕рдордп рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП рдореИрдВ рдкреБрди: рдкреНрд░рд╕реНрддреБрдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛, рд▓реЗрдХрд┐рди рдпрджрд┐ рдореИрдВ рдкреГрд╖реНрда 1 рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реВрдВ рддреЛ рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рд╣реА рдЯреНрд░реЗрд╕рдмреИрдХ рд╣реИред

рдХреБрдЫ рдЬрд╛рдирдХрд╛рд░реА рдЬреЛрдбрд╝рдирд╛: рдХрд░реНрд╕рд░ рдкреЗрдЬрд┐рдиреЗрд╢рди рдореЗрдВ 3 рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ: рд╕реНрдерд┐рддрд┐, рдСрдлрд╝рд╕реЗрдЯ рдФрд░ рдХрд░реНрд╕рд░ред рдмрдЧ рдЪрд╛рд▓реВ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм:

  • рдЖрдк рдПрдХ рдРрд╕реЗ рдкреГрд╖реНрда рдкрд░ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдЕрдм рдХреЛрдИ рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдиреНрд╣реЗрдВ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдЦрд╛рд▓реА рд╕реВрдЪреА рджреЗрддрд╛ рд╣реИ)
  • рдкрд┐рдЫрд▓реЗ рдкреГрд╖реНрда рдХрд╛ рд▓рд┐рдВрдХ, рдкреБрдирдГ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рднреА, рдПрдХ рдСрдлрд╝рд╕реЗрдЯ рд╡рд╛рд▓рд╛ рдХрд░реНрд╕рд░ рд╢рд╛рдорд┐рд▓ рд╣реИ рдФрд░ рдХреЛрдИ рд╕реНрдерд┐рддрд┐ рдирд╣реАрдВ рд╣реИред
  • рдЗрд╕ рд▓рд┐рдВрдХ рдХреЗ рдмрд╛рдж 500 . рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ

рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ self.page рд╡рд┐рд╢реЗрд╖рддрд╛ рдЦрд╛рд▓реА рд╣реИ, рдкреГрд╖реНрда рдореЗрдВ рдХреЛрдИ "рдЕрджреНрд╡рд┐рддреАрдп" рддрддреНрд╡ рдирд╣реАрдВ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдкреГрд╖реНрда рдореЗрдВ рдХреЗрд╡рд▓ рд╡рд╣реА рддрддреНрд╡ рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕рдХреА рд╕реНрдерд┐рддрд┐ рд╕рдорд╛рди рд╣реЛрддреА рд╣реИ, рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдСрдлрд╕реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░рддрд╛ рд╣реИ -рдЖрдзрд╛рд░рд┐рдд рдЖрджреЗрд╢ред

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЯрд┐рдкреНрдкрдгреА:

https://github.com/encode/django-rest-framework/blob/29cbe574a384c3bcc09434a3a9c5ff0cb7576b99/rest_framework/pagination.py#L615

... рддреНрд░реБрдЯрд┐ рд╢рд╛рдорд┐рд▓ рд╣реИред рдпрджрд┐ рдкреГрд╖реНрда рдЦрд╛рд▓реА рд╣реИ рддреЛ рдпрд╣ рдзрд╛рд░рдгрд╛ рдЧрд▓рдд рд╣реИред

рддрд░реНрдХ рдХреЛ рдареАрдХ рдХрд░рдирд╛ рдФрд░ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдкреГрд╖реНрда рдЦрд╛рд▓реА рд╣реИ рдФрд░ рдлрд┐рд░ рд╕реНрдерд┐рддрд┐ рдХреЛ previous_position / next_position рдкрд░ рд╕реЗрдЯ рдХрд░рдирд╛ рдЗрд╕ рдмрдЧ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред

рдкреАрдЖрд░ рдХрд╛ рдкрд╛рд▓рди рдХрд░реЗрдВрдЧреЗред

рдзрдиреНрдпрд╡рд╛рдж @ewjoachim рдФрд░ @tomchristie

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

MadWombat picture MadWombat  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

thnee picture thnee  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

gabn88 picture gabn88  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Lucidiot picture Lucidiot  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

rjdp picture rjdp  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ