• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

barseghyanartur / django-rest-framework-tricks / 3680627646

pending completion
3680627646

push

github

Artur Barseghyan
Up docs

170 of 190 relevant lines covered (89.47%)

4.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.22
/src/rest_framework_tricks/filters/ordering.py
1
"""
2
Ordering filter.
3
"""
4
from rest_framework.filters import OrderingFilter as DjangoOrderingFilter
5✔
5

6
__author__ = "Artur Barseghyan <artur.barseghyan@gmail.com>"
5✔
7
__copyright__ = "2017-2022 Artur Barseghyan"
5✔
8
__license__ = "GPL-2.0-only OR LGPL-2.1-or-later"
5✔
9
__all__ = ("OrderingFilter",)
5✔
10

11

12
class OrderingFilter(DjangoOrderingFilter):
5✔
13
    """Ordering filter improved.
14

15
    Example:
16

17
    >>> from rest_framework_tricks.filters import OrderingFilter
18
    >>>
19
    >>> class BooksViewSet(mixins.RetrieveModelMixin,
20
    >>>                    mixins.ListModelMixin,
21
    >>>                    viewsets.GenericViewSet):
22
    >>>
23
    >>>     serializer_class = BookSerializer
24
    >>>     filter_backends = (
25
    >>>         OrderingFilter,
26
    >>>     )
27
    >>>     ordering_fields = {
28
    >>>         'email': 'user__email',
29
    >>>         'full_name': 'user__first_name',
30
    >>>         'last_login': 'user__last_login',
31
    >>>         'is_active': 'user__is_active',
32
    >>>     }
33

34
    Then it can be used in a view set as follows:
35

36
        GET /books/api/proxy-books/?ordering=email
37
    """
38

39
    def get_valid_fields(self, queryset, view, context=None):
5✔
40
        """Done.
41

42
        :param queryset:
43
        :param view:
44
        :param context:
45
        :return:
46
        """
47
        valid_fields = getattr(view, "ordering_fields", self.ordering_fields)
5✔
48
        if context is None:
5✔
49
            context = {}
×
50

51
        if isinstance(valid_fields, dict):
5✔
52
            return valid_fields.items()
5✔
53
        else:
54
            return super(OrderingFilter, self).get_valid_fields(
5✔
55
                queryset, view, context
56
            )
57

58
    def get_ordering(self, request, queryset, view):
5✔
59
        """Get ordering.
60

61
        Important: list returned in this method is used directly
62
        in the filter_queryset method like:
63

64
        >>> queryset.order_by(*ordering)
65

66
        Ordering is set by a comma delimited ?ordering=... query parameter.
67

68
        The `ordering` query parameter can be overridden by setting
69
        the `ordering_param` value on the OrderingFilter or by
70
        specifying an `ORDERING_PARAM` value in the API settings.
71
        """
72
        valid_fields = getattr(view, "ordering_fields", self.ordering_fields)
5✔
73

74
        # If valid_fields is a dictionary, treat it differently
75
        if isinstance(valid_fields, dict):
5✔
76
            params = request.query_params.get(self.ordering_param)
5✔
77

78
            if params:
5✔
79
                fields = [param.strip() for param in params.split(",")]
5✔
80
                _ordering = self.remove_invalid_fields(
5✔
81
                    queryset, fields, view, request
82
                )
83

84
                ordering = []
5✔
85
                for item in _ordering:
5✔
86
                    if "-" in item:
5✔
87
                        value = valid_fields.get(item[1:])
5✔
88
                        if isinstance(value, (tuple, list)):
5✔
89
                            value = ["-{}".format(__v) for __v in value]
5✔
90
                            ordering += value
5✔
91
                        else:
92
                            ordering.append("-{}".format(value))
5✔
93
                    else:
94
                        value = valid_fields.get(item)
5✔
95
                        if isinstance(value, (tuple, list)):
5✔
96
                            ordering += value
5✔
97
                        else:
98
                            ordering.append(value)
5✔
99
                if ordering:
5✔
100
                    return ordering
5✔
101

102
            # No ordering was included, or all the ordering fields were invalid
103
            return self.get_default_ordering(view)
5✔
104

105
        # In all other cases, use default behaviour
106
        else:
107
            return super(OrderingFilter, self).get_ordering(
5✔
108
                request, queryset, view
109
            )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc