gpt4 book ai didi

python - 使用 django-filters 将多个过滤器合并为一个 filter()

转载 作者:行者123 更新时间:2023-12-04 06:08:09 26 4
gpt4 key购买 nike

我正在使用 django-filter应用程序。但是有一个问题我不知道如何解决。它几乎与 django 文档中描述的完全相同:

https://docs.djangoproject.com/en/1.2/topics/db/queries/#spanning-multi-valued-relationships

我想进行查询,我选择所有包含 条目的博客。两者 标题中的“列侬”发表于 2008 年,例如:

Blog.objects.filter(entry__headline__contains='Lennon', 
entry__pub_date__year=2008)

不要选择标题为“Lennon”的条目和 2008 年发布的另一个条目(可能相同)的博客:
Blog.objects.filter(entry__headline__contains='Lennon').filter(
entry__pub_date__year=2008)

但是,如果我将过滤器设置为有两个字段(没关系__contains x __exact,只是一个示例):
class BlogFilter(django_filters.FilterSet):
entry__headline = django_filters.CharFilter()
entry__pub_date = django_filters.CharFilter()

class Meta:
model = Blog
fields = ['entry__headline', 'entry__pub_date', ]

django-filter 将生成后者:
Blog.objects.filter(entry__headline__exact='Lennon').filter(
entry__pub_date__exact=2008)

有没有办法将两个过滤器组合成一个过滤器字段?

最佳答案

好吧,我提出了一个解决方案。使用常规的 django 过滤器是不可能的,所以我对其进行了一些扩展。本来可以改进的,这是快速解决方案。

1st 向 django_filters.Filter 和 filter_grouped 方法添加了一个自定义的“分组”字段(几乎是过滤器方法的副本)

class Filter(object):

def __init__(self, name=None, label=None, widget=None, action=None,
lookup_type='exact', required=False, grouped=False, **kwargs):
(...)
self.grouped = grouped

def filter_grouped(self, qs, value):
if isinstance(value, (list, tuple)):
lookup = str(value[1])
if not lookup:
lookup = 'exact' # we fallback to exact if no choice for lookup is provided
value = value[0]
else:
lookup = self.lookup_type
if value:
return {'%s__%s' % (self.name, lookup): value}
return {}

唯一的区别是它不是在查询集上创建过滤器,而是返回一个字典。

第二次更新的 BaseFilterSet qs 方法/属性:
class BaseFilterSet(object):
(...)
@property
def qs(self):
if not hasattr(self, '_qs'):
qs = self.queryset.all()
grouped_dict = {}
for name, filter_ in self.filters.iteritems():
try:
if self.is_bound:
data = self.form[name].data
else:
data = self.form.initial.get(name, self.form[name].field.initial)
val = self.form.fields[name].clean(data)
if filter_.grouped:
grouped_dict.update(filter_.filter_grouped(qs, val))
else:
qs = filter_.filter(qs, val)
except forms.ValidationError:
pass

if grouped_dict:
qs = qs.filter(**grouped_dict)

(...)
return self._qs

诀窍是将所有“分组”过滤器存储在字典中,然后将它们全部用作单个过滤器。

过滤器将如下所示:
class BlogFilter(django_filters.FilterSet):
entry__headline = django_filters.CharFilter(grouped=True)
entry__pub_date = django_filters.CharFilter(grouped=True)

class Meta:
model = Blog
fields = ['entry__headline', 'entry__pub_date', ]

关于python - 使用 django-filters 将多个过滤器合并为一个 filter(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8104309/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com