根据请求在Django过滤器ModelChoiceFilter(选择)和ModelMultipleChoiceFilter(多次选择)菜单中自定义查询集 [英] Customize queryset in django-filter ModelChoiceFilter (select) and ModelMultipleChoiceFilter (multi-select) menus based on request
问题描述
我在2个地方使用 django-filter : Django Rest Framework API,并在我的 FilterViews (Django过滤器的通用ListViews。)对于我的FilterViews,我是显示两个选择框( ModelChoiceFilter
I'm using django-filter in 2 places: My Django Rest Framework API, and in my FilterViews (Django Filter's Generic ListViews.) In the case of my FilterViews I'm showing both select boxes (ModelChoiceFilter) and multi-select boxes (ModelMultipleChoiceFilter) to be filtered on.
我需要能够基于a来限制那些select和multi-select输入中的内容
I need to be able to limit what's in those select and multi-select inputs based on a field inside the request.
更改FilterSet中相关字段中列为kwarg的内容相对简单。例如,这是我的FilterSet,其中将查询集设置为kwarg:
It's relatively simple to change what's listed as a kwarg in the relevant field in the FilterSet. For example, here's my FilterSet where the queryset is set as a 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:
And it's relatively straightforward to limit what the result is in DRF inside the get_queryset()
method. For example, here's my 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
我在任何地方都找不到编辑显示视图时,在 filter_class
中的 Dataset
字段中。
I just can't find anywhere to edit the Dataset
field in the filter_class
when the view is being displayed.
这在Django FormView
通用视图中非常简单,但是 FieldViewSet
并没有遵循与普通视图相同的 get_form()
结构。在管理员中这样做也相对简单,但是DRF / Django-Filter似乎也不遵循这种结构。
This is super straightforward in Django FormView
generic views, but it doesn't appear that FieldViewSet
follows the same get_form()
structure as generic views. It's also relatively straightforward to do in the admin, but DRF/Django-Filter don't seem to follow that structure either.
有什么方法可以在其中自定义查询集每个请求的那些输入?最好同时在FilterViews和HTML API浏览器中使用,但如果对于HTML API浏览器来说过于复杂,则仅在FilterViews中就可以了。
Is there any way to customize the queryset in those inputs on a per-request basis? Preferably both on FilterViews and in the HTML API browser, but just in FilterViews would be fine if it's too complicated for the HTML API browser.
推荐答案
经过数小时的搜索,我在官方文档此处!
After hours of search, I found the solution in the official documentation here!
ModelChoiceFilter
和 ModelMultipleChoiceFilter
支持可调用行为。如果传递了可调用对象,则会以 request
作为唯一参数来调用它。
The queryset argument for ModelChoiceFilter
and ModelMultipleChoiceFilter
supports callable behavior. If a callable is passed, it will be invoked with the request
as its only argument.
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', )
视图,我确保也通过了请求
and in the view, I made sure to pass the request
as well
qs = Unit.objects.all()
filter = UnitFilter(self.request.GET, request=self.request, queryset=qs)
table = UnitTable(filter.qs)
这篇关于根据请求在Django过滤器ModelChoiceFilter(选择)和ModelMultipleChoiceFilter(多次选择)菜单中自定义查询集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!