2015-06-23 126 views
1

假設,搜索字段在Django

名爲Education模型包含字段degreefield,和其他模型Resume包含字段skillrole

第三種模式是Candidates並與上述機型外鍵關係。

我希望用戶按skill,role,degreefield搜索候選人。

例如:如果傳遞類似{'java','developer','MS','IT'}的查詢字符串,Django應顯示與查詢字符串中的任何一個值匹配的所有候選字符。

回答

0

如果你使用Django的REST框架(DRF)這樣做,你將要使用django_filtersreferenced 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請求l邁克:

http://www.example.com/rest/SampleSet/?multi_field_srch=foo,de,fa,fa 

會傳回的foodefa所有在田裏field_foobarbaz的至少一個所有SampleSet的。

如果指定參數token_reduceroperator.or_,那麼查詢將返回所有SampleSet S作foodefa任何在田裏field_foo的至少一個,barbaz

最後,token_prefixtoken_suffix是插入通配符(子字符串匹配)或其他前綴或後綴的一種方式。

0

我不認爲有一個自動的方式在Django做到這一點。但是你可以總是或多個搜索一起使用Q. Q的基本用法如下:

from django.db.models import Q 
Education.objects.filter(
    Q(degree__icontains=query) | Q(field__icontains=query) 

要使用的語句(假設查詢是一個列表或者設置使用多個查詢,你可以很容易地建立起來,這些語句的查詢字符串):

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)