views.py
from __future__ import unicode_literals
from rest_framework_mongoengine.viewsets import ModelViewSet as MongoModelViewSet
from app.serializers import *
from rest_framework_mongoengine.generics import *
from rest_framework import filters
def index_view(request):
context = {}
return TemplateResponse(request, 'index.html', context)
class ToolViewSet(MongoModelViewSet):
serializer_class = ToolSerializer
my_filter_fields = ('crop', 'district','taluka','circle','year',)
def get_kwargs_for_filtering(self):
filtering_kwargs = {}
for field in self.my_filter_fields: # iterate over the filter fields
field_value = self.request.query_params.get(field) # get the value of a field from request query parameter
if field_value:
filtering_kwargs[field] = field_value
return filtering_kwargs
def get_queryset(self):
queryset = Tool.objects.all()
filtering_kwargs = self.get_kwargs_for_filtering() # get the fields with values for filtering
if filtering_kwargs:
queryset = Tool.objects.filter(**filtering_kwargs) # filter the queryset based on 'filtering_kwargs'
return queryset
这是我的密码。
这是过滤我们想要讲的东西的工作。
例如:http://api/tool/?district=Nasik&crop=banana
但是,它不适用于列表文件--例如:http://api/tool/?district=Nasik&district=Pune --它给出了输出:空的
如何使该过滤器工作,以得到所有地区"Nasik“或区"Pune”
如果我搜索http://api/tool/?crops=guava,banana或http:./tool/? Pune =Nasik,Pune,请帮助我更改获取数据的代码。
给我正确的输出?
发布于 2017-01-03 00:19:55
我建议看一看django-rest框架-过滤器。然后,您可以在查询参数中使用诸如__in
之类的内容..。
但是,如果您想继续您的方法,我将在您的get_kwargs_for_filtering
方法中添加如下逻辑:
def get_kwargs_for_filtering(self):
filtering_kwargs = {}
for field in self.my_filter_fields: # iterate over the filter fields
field_value = self.request.query_params.get(field) # get the value of a field from request query parameter
if field_value:
if ',' in field_value: # put your queryParams into an array and use the built-in django filter method '__in'
filtering_kwargs[field + '__in'] = field_value.split(',')
else:
filtering_kwargs[field] = field_value
return filtering_kwargs
这样,对http://api/tool/?crops=guava,banana的调用就会产生所需的行为。我现在不能测试它是否有效,但这应该会指引你走向正确的方向。
发布于 2022-11-22 05:37:14
虽然这个问题有点老了。在Django、DRF和MongoEngine的后续版本中,这个问题仍然是重要的和有效的。
在回答这个问题的时候,我正在跑
Django==4.1.3
djangorestframework==3.14
django-rest-framework-mongoengine==3.4.1
mongoengine==0.24.2
django-filter==22.1
# patched version of django-mongoengine-filter to support Django 4.0
# https://github.com/oussjarrousse/django-mongoengine-filter
# Pull request https://github.com/barseghyanartur/django-mongoengine-filter/pull/16
django-mongoengine-filter>=0.3.5
这个答案的思想是使用django-mongoengine-filter
向django-mongoengine-filter
添加过滤支持,这是django-filter
的替代或扩展,应该与django-filter
的工作方式相同。
首先,让我们编辑项目/setings.py文件。查找INSTALLED_APPS变量并确保添加了以下"Django应用程序“:
# in settings.py:
INSTALLED_APPS = [
# ...,
"rest_framework",
"rest_framework_mongoengine",
"django_filters",
# ...,
]
应用程序django_filters需要添加与过滤基础设施相关的类,以及包括用于DRF的html模板在内的其他内容。
然后在变量REST_FRAMEWORK
中,我们需要编辑与键DEFAULT_FILTER_BACKENDS
相关联的值。
# in settings.py:
REST_FRAMEWORK = {
# ...
"DEFAULT_FILTER_BACKENDS": [
"filters.DjangoMongoEngineFilterBackend",
# ...
],
# ...
}
DjangoMongoEngineFilterBackend
是自定义构建的过滤器后端,我们需要将它添加到文件filters
中的文件夹(取决于您如何构造项目)。
# in filters.py:
from django_filters.rest_framework.backends import DjangoFilterBackend
class DjangoMongoEngineFilterBackend(DjangoFilterBackend):
# filterset_base = django_mongoengine_filter.FilterSet
"""
Patching the DjangoFilterBackend to allow for MongoEngine support
"""
def get_filterset_class(self, view, queryset=None):
"""
Return the `FilterSet` class used to filter the queryset.
"""
filterset_class = getattr(view, "filterset_class", None)
filterset_fields = getattr(view, "filterset_fields", None)
if filterset_class:
filterset_model = filterset_class._meta.model
# FilterSets do not need to specify a Meta class
if filterset_model and queryset is not None:
element = queryset.first()
if element:
queryset_model = element.__class__
assert issubclass(
queryset_model, filterset_model
), "FilterSet model %s does not match queryset model %s" % (
filterset_model,
str(queryset_model),
)
return filterset_class
if filterset_fields and queryset is not None:
MetaBase = getattr(self.filterset_base, "Meta", object)
element = queryset.first()
if element:
queryset_model = element.__class__
class AutoFilterSet(self.filterset_base):
class Meta(MetaBase):
model = queryset_model
fields = filterset_fields
return AutoFilterSet
return None
此自定义筛选后端不会引发原始django过滤器后端将引发的异常。django-filter DjangoFilterBackend像在queryset.model
中一样访问QuerySet
中的键model
,但是在MongoEngine中不存在该键。
也许应该考虑在MongoEngine中提供它:https://github.com/MongoEngine/mongoengine/issues/2707 https://github.com/umutbozkurt/django-rest-framework-mongoengine/issues/294
现在,我们可以向ViewSet添加一个自定义筛选器:
# in views.py
from rest_framework_mongoengine.viewsets import ModelViewSet
class MyModelViewSet(ModelViewSet):
serializer_class = MyModelSerializer
filter_fields = ["a_string_field", "a_boolean_field"]
filterset_class = MyModelFilter
def get_queryset(self):
queryset = MyModel.objects.all()
return queryset
最后,让我们回到filters.py
并添加MyModelFilter
# in filters.py
from django_mongoengine_filter import FilterSet, StringField, BooleanField
class MyModelFilter(FilterSet):
"""
MyModelFilter is a FilterSet that is designed to work with the django-filter.
However the original django-mongoengine-filter is outdated and is causing some troubles
with Django>=4.0.
"""
class Meta:
model = MyModel
fields = [
"a_string_field",
"a_boolean_field",
]
a_string_field = StringFilter()
a_boolean_field = BooleanFilter()
这应该能起作用。
https://stackoverflow.com/questions/41424053
复制相似问题