使用 viewsets.py 而非 views.py 向 Django DRF 响应映射 InBBoxFilter 添加标准?
Adding criteria to Django DRF responsive map InBBoxFilter with viewsets.py, not views.py?
我们使用 this tutorial 开发了响应式地图,其中 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 线程和好心人的帮助解决了 in the Django Forums。
我们首先需要让请求包含 GET 值。如果跟随 this tutorial where the request URL is constructed in JS 通过:
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
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
现在我们需要 viewsets.py 使用这些 GET 值过滤查询集。我们可以通过 overriding the filter_queryset(self, queryset)
method:
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
我们使用 this tutorial 开发了响应式地图,其中 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 线程和好心人的帮助解决了 in the Django Forums。
我们首先需要让请求包含 GET 值。如果跟随 this tutorial where the request URL is constructed in JS 通过:
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
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
现在我们需要 viewsets.py 使用这些 GET 值过滤查询集。我们可以通过 overriding the filter_queryset(self, queryset)
method:
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