我在两个地方使用django-filter:我的Django Rest Framework API,以及我的FilterViews(Django过滤器的通用列表视图)。在我的情况下FilterViews我显示了要过滤的选择框(ModelChoiceFilter)和多选框(ModelMultipleChoiceFilter)。
我需要能够根据请求中的字段限制那些选择和多选输入中的内容。
更改在FilterSet中相关字段中列为kwarg的内容相对简单。例如,这里是我的FilterSet,其中查询集被设置为kwarg:
class FieldFilter(django_filters.FilterSet):
"""Filter for the field list in the API"""
dataset = ModelChoiceFilter(queryset=Dataset.objects.all())
class Meta(object):
"""Meta options for the filter"""
model = Field
fields = ['dataset']
在get_queryset()
方法中限制结果在DRF中的相对直接性是相对简单的。例如,这是我的DRF ViewSet:
class FieldViewSet(viewsets.ReadOnlyModelViewSet):
"""A ViewSet for viewing dataset fields"""
queryset = Field.objects.all()
serializer_class = FieldSerializer
filter_class = FieldFilter
def get_queryset(self):
"""Get the queryset"""
queryset = super(FieldViewSet, self).get_queryset()
queryset = queryset.filter(
dataset__organization=self.request.organization)
return queryset
在显示视图时,我无法在Dataset
中找到编辑filter_class
字段的任何位置。
这在Django FormView
通用视图中非常简单,但FieldViewSet
与通用视图遵循相同的get_form()
结构并不显示。它在管理员中也相对简单,但DRF / Django-Filter似乎也不遵循这种结构。
有没有办法在每个请求的基础上自定义这些输入中的查询集?最好是在FilterViews和HTML API浏览器中,但只有在FilterViews中,如果HTML API浏览器过于复杂,那就没问题。
答案 0 :(得分:2)
我也很难找到解决方法。
我通过以下方法解决了(我认为):
views.py
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.css" />
</head>
<body>
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.2.0/vuetify.min.js"></script>
</body>
</html>
filters.py
table_filter = ExampleFilter(request.GET, kwarg_I_want_to_pass=request.user, queryset=qs)
答案 1 :(得分:1)
经过数小时的搜索,我在官方文档here中找到了解决方案!
ModelChoiceFilter
和ModelMultipleChoiceFilter
的queryset参数支持可调用行为。如果传递了Callable,它将以request
作为其唯一参数来调用。
import django_filters as filters
from django.utils.translation import gettext as _
def ourBranches(request):
if request is None:
return Branch.objects.none()
company = request.user.profile.company
return Branch.objects.filter(company=company)
class UnitFilter(filters.FilterSet):
branch = filters.ModelChoiceFilter(
queryset=ourBranches, empty_label=_("All Branches"))
class Meta:
model = Unit
fields = ('branch', )
在视图中,我还确保也通过了request
qs = Unit.objects.all()
filter = UnitFilter(self.request.GET, request=self.request, queryset=qs)
table = UnitTable(filter.qs)