尝试使用 django 过滤器为给定模型中的所有字段创建一般搜索
Posted
技术标签:
【中文标题】尝试使用 django 过滤器为给定模型中的所有字段创建一般搜索【英文标题】:Trying to create a general search using django filters for all the fields in a given model 【发布时间】:2019-11-10 11:41:30 【问题描述】:所以我正在为我的模型创建一个自定义过滤器,我希望该过滤器中的所有字段不使用“精确”而是“包含”,但我不想手动添加所有字段。我正在尝试做这样的事情:
from django_filters import FilterSet
from polls.models import Question, Choice
from django_filters import rest_framework
class ChoiceFilter(FilterSet):
for field in Choice._meta.get_fields():
field = rest_framework.CharFilter(lookup_expr='icontains')
#question = rest_framework.CharFilter(lookup_expr='icontains') #this works want to generalize this
class Meta:
model = Choice
fields = '__all__'
所以第二行有效,但我的 for 循环无效,我的过滤器使用 'exact' 而不是 'contains'
【问题讨论】:
【参考方案1】:您可以创建一个自定义的FilterSet
类,它会覆盖get_fields
方法来将查找从exact
更改为icontains
:
class CustomFilterSet(FilterSet):
@classmethod
def get_fields(cls):
fields = super().get_fields()
for name, lookups in fields.items():
lookups[:] = ['icontains']
return fields
现在你只需让ChoiceFilter
继承这个类:
class ChoiceFilter(CustomFilterSet):
class Meta:
model = Choice
fields = '__all__'
请记住,将__all__
用于字段是很危险的。
【讨论】:
谢谢!这似乎主要工作,我只是收到一个错误,上面写着'django_filters.exceptions.FieldLookupError:字段'polls.Choice.question'的不支持查找'icontains'。'。我很确定这个错误是因为“问题”是一个外键,你知道我怎么可能解决这个问题吗? 你是对的。您要么需要明确声明所有字段,要么使用exclude 排除question
字段。
你知道在一个模型中获取所有外键的方法吗? (没关系,我可以自己进行搜索,但非常感谢!)
为此您可以使用get_fields
方法,但不建议这样做。如果您向 Choice
模型添加新字段,您的 ChoiceFilterSet
将被隐式更改。
你认为这样的事情会奏效吗? ` blackList = [] for field in Choice._meta.fields: if field.get_internal_type() == 'ForeignKey': blackList.append(field.__name__) exclude = blackList`【参考方案2】:
在我的用例中,我需要通过多个基于日期的查找表达式过滤单个 DateTimeField。最有效的方法是在我的字段字典中使用 date__ 前缀:
# Bullet Filter
class BulletFilter(filters.FilterSet):
class Meta:
model = Bullet
fields =
'bullet_header': ['icontains'],
'bullet_cite_date': ['iexact', 'gte', 'lte'],
'created': ['date__iexact', 'date__gte', 'date__lte'],
'updated': ['date__iexact', 'date__gte', 'date__lte'],
这里bullet_header是CharField,bullet_cite_date是DateField,created和updated是DateTimeFields。
【讨论】:
【参考方案3】:从 django-filter v2.3 开始,您可以在 settings.py
中定义 FILTERS_DEFAULT_LOOKUP_EXPR = 'icontains'
,这将改变默认行为。
【讨论】:
以上是关于尝试使用 django 过滤器为给定模型中的所有字段创建一般搜索的主要内容,如果未能解决你的问题,请参考以下文章