Django-rest-framework: IndexError لـ CursorPagination عندما تتغير مجموعة الاستعلام

تم إنشاؤها على ١١ مارس ٢٠١٩  ·  4تعليقات  ·  مصدر: encode/django-rest-framework

قائمة تدقيق

  • [X] لقد تحققت من وجود هذه المشكلة مقابل فرع master من إطار عمل Django REST.
  • [x] لقد بحثت عن مشكلات مماثلة في كل من التذاكر المفتوحة والمغلقة ولا يمكنني العثور على نسخة مكررة.
  • [x] هذا ليس سؤال استخدام. (يجب توجيه هؤلاء إلى مجموعة المناقشة بدلاً من ذلك).
  • [x] لا يمكن التعامل مع هذا كمكتبة طرف ثالث. (نفضل أن تكون الوظائف الجديدة في شكل مكتبات تابعة لجهات خارجية حيثما أمكن ذلك.)
  • [x] لقد اختزلت المشكلة إلى أبسط حالة ممكنة.
  • [x] لقد قمت بتضمين اختبار فاشل كطلب سحب. (إذا لم تتمكن من القيام بذلك ، فلا يزال بإمكاننا قبول المشكلة.)

خطوات التكاثر

  1. تمكين CursorPagination
  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 التقييمات