Python 在Django中搜索多个模型中的字段
假设 名为Python 在Django中搜索多个模型中的字段,python,django,django-models,django-rest-framework,Python,Django,Django Models,Django Rest Framework,假设 名为教育的模型包含字段学位和字段,其他模型简历包含字段技能和角色 第三个模型是候选者,与上述模型有外键关系 我希望用户按其技能、角色、学位或字段搜索候选人 例如:如果传递了像{'java'、'developer'、'MS'、'IT'}这样的查询字符串,Django应该显示与查询字符串中任何一个值匹配的所有候选项。我认为Django中没有自动执行此操作的方法。但您可以使用Q始终或同时进行多个搜索。Q的基本用法如下: from django.db.models import Q Educati
教育
的模型包含字段学位
和字段
,其他模型简历
包含字段技能
和角色
第三个模型是候选者
,与上述模型有外键关系
我希望用户按其技能
、角色
、学位
或字段
搜索候选人
例如:如果传递了像
{'java'、'developer'、'MS'、'IT'}
这样的查询字符串,Django应该显示与查询字符串中任何一个值匹配的所有候选项。我认为Django中没有自动执行此操作的方法。但您可以使用Q始终或同时进行多个搜索。Q的基本用法如下:
from django.db.models import Q
Education.objects.filter(
Q(degree__icontains=query) | Q(field__icontains=query)
要使用多个查询,您可以使用for语句轻松地将这些语句构建在一起(假设查询是查询字符串的列表或集合):
现在,您需要搜索多个模型,因此您还必须包括这些连接。从你的问题中不太清楚你想如何搜索,但我猜你基本上想搜索候选词,所有关键词都需要与找到的项目匹配。所以查询可以这样做:
q = Q()
for query in queries
q = (q & (Q(education__degree__icontains=query) |
Q(education__field__icontains=query) |
Q(resume__skill__icontains=query) |
Q(resume__role__icontains=query)
Q(skill__icontains=query) |
Q(role__icontains=query) |
Q(degree__icontains=query) |
Q(field__icontains=query)))
return Candidate.objects.filter(q)
class SampleSetFilter(django_filters.FilterSet):
multi_field_search = MultiFieldFilter(names=["field_foo", "bar", "baz"],lookup_type='in')
class Meta:
model = SampleSet
fields = ('multi_field_srch',)
我不认为在django有一种自动的方式来做这件事。但您可以使用Q始终或同时进行多个搜索。Q的基本用法如下:
from django.db.models import Q
Education.objects.filter(
Q(degree__icontains=query) | Q(field__icontains=query)
要使用多个查询,您可以使用for语句轻松地将这些语句构建在一起(假设查询是查询字符串的列表或集合):
现在,您需要搜索多个模型,因此您还必须包括这些连接。从你的问题中不太清楚你想如何搜索,但我猜你基本上想搜索候选词,所有关键词都需要与找到的项目匹配。所以查询可以这样做:
q = Q()
for query in queries
q = (q & (Q(education__degree__icontains=query) |
Q(education__field__icontains=query) |
Q(resume__skill__icontains=query) |
Q(resume__role__icontains=query)
Q(skill__icontains=query) |
Q(role__icontains=query) |
Q(degree__icontains=query) |
Q(field__icontains=query)))
return Candidate.objects.filter(q)
class SampleSetFilter(django_filters.FilterSet):
multi_field_search = MultiFieldFilter(names=["field_foo", "bar", "baz"],lookup_type='in')
class Meta:
model = SampleSet
fields = ('multi_field_srch',)
如果您使用Django Rest框架(DRF)执行此操作,您将希望使用as 为了实现您在我的项目中所说的,我创建了一个django_过滤器的通用扩展。过滤器:
import operator
from django.db.models import Q
import django_filters
class MultiFieldFilter(django_filters.Filter):
def __init__(self,names,*args,**kwargs):
if len(args) == 0:
kwargs['name'] = names[0]
self.token_prefix = kwargs.pop('token_prefix','')
self.token_suffix = kwargs.pop('token_suffix','')
self.token_reducer = kwargs.pop('token_reducer',operator.and_)
self.names = names
django_filters.Filter.__init__(self,*args,**kwargs)
def filter(self,qs,value):
if value not in (None,''):
tokens = value.split(',')
return qs.filter(
reduce(
self.token_reducer,
[
reduce(
operator.or_,
[Q(**{
'%s__icontains'%name:
(self.token_prefix+token+self.token_suffix)})
for name in self.names])
for token in tokens]))
return qs
这在django_过滤器中使用。过滤器集
如下:
q = Q()
for query in queries
q = (q & (Q(education__degree__icontains=query) |
Q(education__field__icontains=query) |
Q(resume__skill__icontains=query) |
Q(resume__role__icontains=query)
Q(skill__icontains=query) |
Q(role__icontains=query) |
Q(degree__icontains=query) |
Q(field__icontains=query)))
return Candidate.objects.filter(q)
class SampleSetFilter(django_filters.FilterSet):
multi_field_search = MultiFieldFilter(names=["field_foo", "bar", "baz"],lookup_type='in')
class Meta:
model = SampleSet
fields = ('multi_field_srch',)
其实例化如下:
class SampleSetViewSet(viewsets.ModelViewSet):
queryset = SampleSet.objects.all()
serializer_class = SampleSetSerializer
filter_class = SampleSetFilterSet # <- and vvvvvvvvvvvvvvvvvvvvvvvvvvvv
filter_backends = (filters.OrderingFilter, filters.DjangoFilterBackend,)
将在至少一个字段field\u foo
、bar
或baz
中返回包含所有foo
、de
和fa
的所有SampleSet
如果将参数token\u reducer
指定为运算符或
,则该查询将返回所有样本集
,这些样本集至少在字段
、条
或baz
中的一个字段中具有foo
、de
或fa
最后,
token\u prefix
和token\u suffix
是插入通配符(子字符串匹配)或其他前缀或后缀的一种方法。如果使用Django Rest Framework(DRF)执行此操作,则需要使用as
为了实现您在我的项目中所说的,我创建了一个django_过滤器的通用扩展。过滤器:
import operator
from django.db.models import Q
import django_filters
class MultiFieldFilter(django_filters.Filter):
def __init__(self,names,*args,**kwargs):
if len(args) == 0:
kwargs['name'] = names[0]
self.token_prefix = kwargs.pop('token_prefix','')
self.token_suffix = kwargs.pop('token_suffix','')
self.token_reducer = kwargs.pop('token_reducer',operator.and_)
self.names = names
django_filters.Filter.__init__(self,*args,**kwargs)
def filter(self,qs,value):
if value not in (None,''):
tokens = value.split(',')
return qs.filter(
reduce(
self.token_reducer,
[
reduce(
operator.or_,
[Q(**{
'%s__icontains'%name:
(self.token_prefix+token+self.token_suffix)})
for name in self.names])
for token in tokens]))
return qs
这在django_过滤器中使用。过滤器集
如下:
q = Q()
for query in queries
q = (q & (Q(education__degree__icontains=query) |
Q(education__field__icontains=query) |
Q(resume__skill__icontains=query) |
Q(resume__role__icontains=query)
Q(skill__icontains=query) |
Q(role__icontains=query) |
Q(degree__icontains=query) |
Q(field__icontains=query)))
return Candidate.objects.filter(q)
class SampleSetFilter(django_filters.FilterSet):
multi_field_search = MultiFieldFilter(names=["field_foo", "bar", "baz"],lookup_type='in')
class Meta:
model = SampleSet
fields = ('multi_field_srch',)
其实例化如下:
class SampleSetViewSet(viewsets.ModelViewSet):
queryset = SampleSet.objects.all()
serializer_class = SampleSetSerializer
filter_class = SampleSetFilterSet # <- and vvvvvvvvvvvvvvvvvvvvvvvvvvvv
filter_backends = (filters.OrderingFilter, filters.DjangoFilterBackend,)
将在至少一个字段field\u foo
、bar
或baz
中返回包含所有foo
、de
和fa
的所有SampleSet
如果将参数token\u reducer
指定为运算符或
,则该查询将返回所有样本集
,这些样本集至少在字段
、条
或baz
中的一个字段中具有foo
、de
或fa
最后,token\u前缀
和token\u后缀
是插入通配符(子字符串匹配)或其他前缀或后缀的一种方法。我使用它在Django Rest框架中搜索多个模型。确保仔细阅读文档,尤其是说明如何设置端点的文档。它的构建和文档记录似乎非常完善,支持我所期望的一切,如限制和过滤器。我使用它在Django Rest框架中搜索多个模型。确保仔细阅读文档,尤其是说明如何设置端点的文档。它似乎构建得很好,文档化程度很高,支持我所期望的一切,比如限制和过滤器