假设,
名为Education
的模型包含字段degree
和field
,其他模型Resume
包含字段skill
和role
。< / p>
第三个模型是Candidates
,并且与上述模型具有外键关系。
我希望用户按skill
,role
,degree
或field
搜索候选人。
例如:如果传递了像{'java','developer','MS','IT'}
这样的查询字符串,Django应该显示匹配查询字符串中任何一个值的所有候选字符。
答案 0 :(得分:0)
我认为在django中有一种自动方式可以做到这一点。但是你总是可以使用Q一起进行OR多次搜索.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(degree__icontains=query) | Q(field__icontains=query)
Education.objects.filter(q)
现在您想要搜索多个模型,因此您还必须包含这些连接。从您的问题来看,您的搜索方式并不完全清楚,但我猜您基本上希望搜索候选项,并且所有关键字都需要与找到的项目匹配。所以查询可以像这样完成:
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)
答案 1 :(得分:0)
如果您使用Django Rest Framework(DRF)执行此操作,则需要将django_filters用作referenced by DRF。
要在我的项目中执行您正在谈论的内容,我创建了django_filters.Filter
的通用扩展名:
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_filter.FilterSet
中使用,如下所示:
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,)
最后,GET
请求如下:
http://www.example.com/rest/SampleSet/?multi_field_srch=foo,de,fa,fa
将返回所有 SampleSet
,foo
,和 {{1}的所有de
至少在其中一个字段fa
,field_foo
或bar
中。
如果您将参数baz
指定为token_reducer
,则该查询将返回任何 operator.or_
的所有SampleSet
,{至少有一个字段foo
,de
或fa
中的{1}},或 field_foo
。
最后,bar
和baz
是一种插入通配符(子字符串匹配)或其他前缀或后缀的方法。
答案 2 :(得分:0)
我正在使用Django Rest Multiple Models在Django Rest Framework中搜索多个模型。请务必仔细阅读文档,尤其是section on using viewsets,它解释了如何设置端点。它看起来真的很好构建并记录在案,并且可以支持我期望的所有内容,例如限制和过滤器。