У меня есть маленький Франкенштейн:
from dynamic_rest.viewsets import DynamicModelViewSet
class QuarterFilter(django_filters.Filter):
def get_quarter_range(self, quarter):
if quarter == 1:
return [1, 3]
elif quarter == 2:
return [4, 6]
elif quarter == 3:
return [7, 9]
elif quarter == 4:
return [10, 12]
else:
raise ValidationError("quarter value must be range from 1-4")
def filter(self, qs, value):
try:
year, quarter = value.split("Q")
year, quarter = int(year), int(quarter)
qs = qs.filter(date__year=year)
qs = qs.filter(date__month__range=self.get_quarter_range(quarter))
except:
pass
return qs
class OperationViewSet(DynamicModelViewSet):
queryset = Operation.objects.all()
serializer_class = OperationSerializer
permission_classes = (AllowAny,)
def get_queryset(self, *args, **kwargs):
# TODO: how to implement a .quarter operator at the Dynamic REST level?
queryset = Operation.objects.all()
quarter = self.request.query_params.pop('filter{date.quarter}')
if quarter:
queryset = QuarterFilter().filter(queryset, quarter[0])
return queryset
Что представляет собой смесь Dynamic Rest и Django Filter
.
Это работает, но мне это не нравится, особенно потому, что if не допускает никакой гибкости при выборе поля, к которому применяется фильтр: в настоящее время он жестко задан в date.quarter
. Я не хочу расширять эту концепцию, изобретая колесо. Вместо этого я хотел бы расширить мощный механизм, реализованный динамическим отдыхом. Динамический отдых поддерживает кучу операторов .
Каким будет приемлемый способ расширения списка операторов, включив в него оператор .quarter
, реализующий вышеуказанную функциональность?