Добавление критериев в Django DRF отзывчивой карты InBBoxFilter с помощью viewsets.py, а не views.py?
Мы разработали отзывчивую карту, используя этот учебник, где Django Rest Framework обслуживает ответы, которые заполняют карту. Мой viewsets.py:
class MarkerViewSet(viewsets.ReadOnlyModelViewSet):
"""Marker view set."""
bbox_filter_field = "geom"
filter_backends = (filters.InBBoxFilter,)
queryset = Tablename.objects.all()
serializer_class = MarkerSerializer
pagination_class = GeoPaginator
Я хотел бы добавить необязательные критерии в этот фильтр, если они встречаются в значении GET. Остальная часть моего проекта использует views.py, который фильтрует вещи по-другому. Мой упрощенный views.py, который делает это для чего-то другого:
def EgFilterView(request):
qs = Tablename.objects.all()
date_min_query = request.GET.get('dmin')
min_date = 1970
qs = qs.filter(date__gte=dt.datetime(int(date_min_query), 1, 1, tzinfo=pytz.UTC))
context = {
'queryset': qs,
'dmin': min_date,
}
return render(request, "main_page.html", context)
Но похоже, что viewsets.py не обрабатывает значения .get()
таким образом, а вместо этого использует .list()
и .create()
, что мне непонятно.
Как я могу включить дополнительные фильтры в мой viewsets.py для дальнейшей фильтрации вещей с GET-значениями? Будет ли лучше попытаться преобразовать этот viewsets.py / другие сложные вещи API, которые я не понимаю, в views.py?
Выяснил это с помощью других потоков SO и помощи добрых людей на форумах Django.
Сначала нам нужно сделать так, чтобы запрос включал значения GET. Если следовать этому руководству, где URL запроса строится в JS через: Нужно добавить строку с другими входами и их значениями: Теперь нам нужно заставить viewsets.py фильтровать кверисет с этими значениями GET. Мы можем сделать это путем переопределения метода const markers_url = `/api/markers/?in_bbox=${map.getBounds().toBBoxString()}`
const form = document.querySelector('#theForm'); // supply ID of form containing inputs
var object = Object.values(form).reduce((obj,field) => { obj[field.name] = field.value; return obj }, {}); // get an object of all inputs and values https://stackoverflow.com/a/47188324
delete object[""]; // remove empty string we couldn't figure out cause of
const markers_url = `/api/markers/?in_bbox=${map.getBounds().toBBoxString()}` + '&' + new URLSearchParams(object).toString() // make this object a string in URLSearchParams format and suffix to url
filter_queryset(self, queryset)
:class MarkerViewSet(viewsets.ReadOnlyModelViewSet):
"""Marker view set."""
bbox_filter_field = "geom"
filter_backends = (filters.InBBoxFilter,)
queryset = Tablename.objects.all()
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
extra_field1 = self.request.query_params.get('extra_field1') # creates string of the GET param "extra_field1"
if extra_field1:
queryset = queryset.filter(extra_field1=extra_field1) # filter here as desired
return queryset
serializer_class = MarkerSerializer
pagination_class = GeoPaginator