将附加属性传递给 django-filter
Pass additional attribute to django-filter
我将 django-filter 与 DRF 一起使用。我有一个 favourite
-模型,它通过 GenericRelation 链接到其他几个模型。
为了过滤具有 favourite-flag 的条目,我创建了一个自定义 FavouriteFilter
,并将其添加到相应的模型中。我想查询相应模型的 content_type_id
以限制来自 Favourite
的结果。但是,我不知道如何将 model
传递给 FavouriteFilter
中的 filter-method。
这里有一个代码片段来说明这个问题:
class ProjectFilter(BaseFilter):
favourite_only = FavouriteFilter()
class FavouriteFilter(django_filters.BooleanFilter):
"""
A custom filter which returns a users favourites of an element
"""
def __init__(self, *args, **kwargs):
# gettext_lazy breaks the OpenAPI generation => use gettext instead
kwargs['label'] = gettext("My favourites")
super(FavouriteFilter, self).__init__(*args, **kwargs)
def filter(self, qs, value):
if value == True:
user = get_current_user()
content_type = ContentType.objects.get_for_model(<model>)
return qs.filter(pk__in=Favourite.objects
.filter(owner_id=user)
.filter(content_type_id=content_type)
.values_list('object_id', flat=True)
)
else:
return qs
在此示例中,缺少 <model>
属性。如何将此信息从 Project
传递给过滤器?
关键字参数可以传递给过滤器,但在调用 super() 方法之前需要将它们从 kwarg-dict 中删除。否则它们会被传递给超类,超类的 __init__()
方法不知道关键字并抛出 TypeError
:
TypeError: __init__() got an unexpected keyword argument 'model'
在上面的例子中,超类分别是django_filters.BooleanFilter
django_filters.Filter
.
使用dict.pop()
-方法,关键字从kwargs-dictionary中删除,同时我们可以保存它以供进一步使用。由于 content_type
在初始化后不会改变,所以它已经可以设置在 __init__()
.
这是上面代码的一个工作示例,其中 Project
是我要传递给过滤器的 django-model:
class ProjectFilter(BaseFilter):
favourite_only = FavouriteFilter(model=Project)
class FavouriteFilter(django_filters.BooleanFilter):
"""
A custom filter which returns a users favourites of an element
"""
def __init__(self, *args, **kwargs):
# gettext_lazy breaks the OpenAPI generation => use gettext instead
kwargs['label'] = gettext("My favourites")
model = kwargs.pop('model')
self.content_type = ContentType.objects.get_for_model(model)
super(FavouriteFilter, self).__init__(*args, **kwargs)
def filter(self, qs, value):
if value == True:
user = get_current_user()
return qs.filter(pk__in=Favourite.objects
.filter(owner_id=user)
.filter(content_type_id=self.content_type)
.values_list('object_id', flat=True)
)
else:
return qs
对于我的特定 use-case,我正在寻找使用过滤器的模型,该模型可通过查询集作为 qs.model
获得。 code-snippet 看起来像这样:
class ProjectFilter(BaseFilter):
favourite_only = FavouriteFilter()
class FavouriteFilter(django_filters.BooleanFilter):
"""
A custom filter which returns a users favourites of an element
"""
def __init__(self, *args, **kwargs):
# gettext_lazy breaks the OpenAPI generation => use gettext instead
kwargs['label'] = gettext("My favourites")
super(FavouriteFilter, self).__init__(*args, **kwargs)
def filter(self, qs, value):
if value == True:
user = get_current_user()
content_type = ContentType.objects.get_for_model(qs.model)
return qs.filter(pk__in=Favourite.objects
.filter(owner_id=user)
.filter(content_type_id=content_type)
.values_list('object_id', flat=True)
)
else:
return qs
我将 django-filter 与 DRF 一起使用。我有一个 favourite
-模型,它通过 GenericRelation 链接到其他几个模型。
为了过滤具有 favourite-flag 的条目,我创建了一个自定义 FavouriteFilter
,并将其添加到相应的模型中。我想查询相应模型的 content_type_id
以限制来自 Favourite
的结果。但是,我不知道如何将 model
传递给 FavouriteFilter
中的 filter-method。
这里有一个代码片段来说明这个问题:
class ProjectFilter(BaseFilter):
favourite_only = FavouriteFilter()
class FavouriteFilter(django_filters.BooleanFilter):
"""
A custom filter which returns a users favourites of an element
"""
def __init__(self, *args, **kwargs):
# gettext_lazy breaks the OpenAPI generation => use gettext instead
kwargs['label'] = gettext("My favourites")
super(FavouriteFilter, self).__init__(*args, **kwargs)
def filter(self, qs, value):
if value == True:
user = get_current_user()
content_type = ContentType.objects.get_for_model(<model>)
return qs.filter(pk__in=Favourite.objects
.filter(owner_id=user)
.filter(content_type_id=content_type)
.values_list('object_id', flat=True)
)
else:
return qs
在此示例中,缺少 <model>
属性。如何将此信息从 Project
传递给过滤器?
关键字参数可以传递给过滤器,但在调用 super() 方法之前需要将它们从 kwarg-dict 中删除。否则它们会被传递给超类,超类的 __init__()
方法不知道关键字并抛出 TypeError
:
TypeError: __init__() got an unexpected keyword argument 'model'
在上面的例子中,超类分别是django_filters.BooleanFilter
django_filters.Filter
.
使用dict.pop()
-方法,关键字从kwargs-dictionary中删除,同时我们可以保存它以供进一步使用。由于 content_type
在初始化后不会改变,所以它已经可以设置在 __init__()
.
这是上面代码的一个工作示例,其中 Project
是我要传递给过滤器的 django-model:
class ProjectFilter(BaseFilter):
favourite_only = FavouriteFilter(model=Project)
class FavouriteFilter(django_filters.BooleanFilter):
"""
A custom filter which returns a users favourites of an element
"""
def __init__(self, *args, **kwargs):
# gettext_lazy breaks the OpenAPI generation => use gettext instead
kwargs['label'] = gettext("My favourites")
model = kwargs.pop('model')
self.content_type = ContentType.objects.get_for_model(model)
super(FavouriteFilter, self).__init__(*args, **kwargs)
def filter(self, qs, value):
if value == True:
user = get_current_user()
return qs.filter(pk__in=Favourite.objects
.filter(owner_id=user)
.filter(content_type_id=self.content_type)
.values_list('object_id', flat=True)
)
else:
return qs
对于我的特定 use-case,我正在寻找使用过滤器的模型,该模型可通过查询集作为 qs.model
获得。 code-snippet 看起来像这样:
class ProjectFilter(BaseFilter):
favourite_only = FavouriteFilter()
class FavouriteFilter(django_filters.BooleanFilter):
"""
A custom filter which returns a users favourites of an element
"""
def __init__(self, *args, **kwargs):
# gettext_lazy breaks the OpenAPI generation => use gettext instead
kwargs['label'] = gettext("My favourites")
super(FavouriteFilter, self).__init__(*args, **kwargs)
def filter(self, qs, value):
if value == True:
user = get_current_user()
content_type = ContentType.objects.get_for_model(qs.model)
return qs.filter(pk__in=Favourite.objects
.filter(owner_id=user)
.filter(content_type_id=content_type)
.values_list('object_id', flat=True)
)
else:
return qs