79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from django.db.models import Q
|
|
|
|
from rest_framework import filters
|
|
|
|
|
|
class QueryParamsFilterMixin(object):
|
|
_special_values_dict = {
|
|
'true': True,
|
|
'false': False,
|
|
'null': None,
|
|
}
|
|
|
|
def filter_queryset(self, request, queryset, view):
|
|
query_params = {}
|
|
|
|
if not hasattr(view, "filter_fields"):
|
|
return queryset
|
|
|
|
for field in view.filter_fields:
|
|
if isinstance(field, (tuple, list)):
|
|
param_name, field_name = field
|
|
else:
|
|
param_name, field_name = field, field
|
|
|
|
if param_name in request.QUERY_PARAMS:
|
|
field_data = request.QUERY_PARAMS[param_name]
|
|
if field_data in self._special_values_dict:
|
|
query_params[field_name] = self._special_values_dict[field_data]
|
|
else:
|
|
query_params[field_name] = field_data
|
|
|
|
if query_params:
|
|
queryset = queryset.filter(**query_params)
|
|
|
|
return queryset
|
|
|
|
class OrderByFilterMixin(object):
|
|
order_by_query_param = "order_by"
|
|
|
|
def filter_queryset(self, request, queryset, view):
|
|
queryset = super().filter_queryset(request, queryset, view)
|
|
order_by_fields = getattr(view, "order_by_fields", None)
|
|
|
|
raw_fieldname = request.QUERY_PARAMS.get(self.order_by_query_param, None)
|
|
if not raw_fieldname or not order_by_fields:
|
|
return queryset
|
|
|
|
if raw_fieldname.startswith("-"):
|
|
field_name = raw_fieldname[1:]
|
|
else:
|
|
field_name = raw_fieldname
|
|
|
|
if field_name not in order_by_fields:
|
|
return queryset
|
|
|
|
return queryset.order_by(raw_fieldname)
|
|
|
|
|
|
class FilterBackend(OrderByFilterMixin,
|
|
QueryParamsFilterMixin,
|
|
filters.BaseFilterBackend):
|
|
"""
|
|
Default filter backend.
|
|
"""
|
|
pass
|
|
|
|
|
|
class IsProjectMemberFilterBackend(FilterBackend):
|
|
def filter_queryset(self, request, queryset, view):
|
|
queryset = super().filter_queryset(request, queryset, view)
|
|
user = request.user
|
|
|
|
if user.is_authenticated():
|
|
queryset = queryset.filter(Q(project__members=request.user) |
|
|
Q(project__owner=request.user))
|
|
return queryset.distinct()
|