-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: removable annotations on pagination
- Loading branch information
Showing
7 changed files
with
210 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
"""Monkey patches defined here.""" | ||
from __future__ import annotations | ||
|
||
from typing import Any | ||
|
||
from django.db.models.query import QuerySet | ||
|
||
original_queryset_chain = QuerySet._chain # pylint: disable=protected-access | ||
|
||
|
||
def customized_queryset_chain(self: Any, **kwargs: Any) -> QuerySet: | ||
"""Customized queryset chain method for the QuerySet class.""" | ||
result = original_queryset_chain(self, **kwargs) | ||
|
||
if hasattr(self, 'removable_annotations'): | ||
result.removable_annotations = self.removable_annotations.copy() | ||
|
||
return result | ||
|
||
|
||
QuerySet._chain = customized_queryset_chain # pylint: disable=protected-access |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,28 @@ | ||
"""Pagination helpers and classes for the API views.""" | ||
from django.core.paginator import Paginator | ||
from django.db.models.query import QuerySet | ||
from django.utils.functional import cached_property | ||
from rest_framework.pagination import PageNumberPagination | ||
|
||
|
||
class DefaultPaginator(Paginator): | ||
"""Default paginator settings for the API views.""" | ||
@cached_property | ||
def count(self) -> int: | ||
"""Return the total number of objects, across all pages.""" | ||
if isinstance(self.object_list, QuerySet) and hasattr(self.object_list, 'removable_annotations'): | ||
clone = self.object_list._chain() # pylint: disable=protected-access | ||
for key in self.object_list.removable_annotations: | ||
clone.query.annotations.pop(key, None) | ||
return clone.count() | ||
|
||
return super().count | ||
|
||
|
||
class DefaultPagination(PageNumberPagination): | ||
"""Default pagination settings for the API views.""" | ||
page_size: int = 20 | ||
page_size_query_param: str = 'page_size' | ||
max_page_size: int = 100 | ||
|
||
django_paginator_class = DefaultPaginator |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
"""Tests for monkey patches""" | ||
from unittest.mock import MagicMock, patch | ||
|
||
from django.db.models.query import QuerySet | ||
|
||
from futurex_openedx_extensions.helpers.monkey_patches import customized_queryset_chain | ||
|
||
|
||
def test_queryset_chain(): | ||
"""Verify that the original_queryset_chain is correctly defined.""" | ||
assert QuerySet._chain == customized_queryset_chain # pylint: disable=protected-access, comparison-with-callable | ||
|
||
|
||
@patch('futurex_openedx_extensions.helpers.monkey_patches.original_queryset_chain') | ||
def test_customized_queryset_chain_has_attribute(mock_original_queryset_chain): | ||
"""Verify that the customized_queryset_chain is correctly defined.""" | ||
mock_original_queryset_chain.return_value = MagicMock(spec=QuerySet) | ||
del mock_original_queryset_chain.return_value.removable_annotations | ||
|
||
mock_queryset = MagicMock(spec=QuerySet) | ||
mock_queryset.removable_annotations = {'annotation1'} | ||
mock_queryset._chain.return_value = mock_queryset # pylint: disable=protected-access | ||
|
||
result = customized_queryset_chain(mock_queryset) | ||
assert result.removable_annotations == mock_queryset.removable_annotations | ||
mock_original_queryset_chain.assert_called_once_with(mock_queryset) | ||
|
||
|
||
@patch('futurex_openedx_extensions.helpers.monkey_patches.original_queryset_chain') | ||
def test_customized_queryset_chain_no_attribute(mock_original_queryset_chain): | ||
"""Verify that the customized_queryset_chain is correctly defined.""" | ||
mock_original_queryset_chain.return_value = MagicMock(spec=QuerySet) | ||
delattr( # pylint: disable=literal-used-as-attribute | ||
mock_original_queryset_chain.return_value, 'removable_annotations', | ||
) | ||
|
||
mock_queryset = MagicMock(spec=QuerySet) | ||
del mock_queryset.removable_annotations | ||
mock_queryset._chain.return_value = mock_queryset # pylint: disable=protected-access | ||
|
||
result = customized_queryset_chain(mock_queryset) | ||
assert not hasattr(result, 'removable_annotations') | ||
mock_original_queryset_chain.assert_called_once_with(mock_queryset) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters