2013-10-03 14 views
0

我想在tastypie中过滤结果以获得符合同一字段上两个过滤器的结果。如何在TastyPie的URL中的相同字段上构建AND查询?

所以,如果我有这样一个简单的模型......

class Item(models.Model): 
    name = models.CharField(max_length=255) 
    description = models.TextField() 

随着ModelResource ...

class ItemResource(ModelResource): 
    ... 
    class Meta(): 
     queryset = Item.objects.all() 
     resource_name = 'item' 
     filtering = {'name': ALL, 'description': ALL} 

我可以很容易地构建 '和' 在tastypie的网址查询:

/api/v1/item/?name__contains=hello&description__contains=foo 

但是,如果我想构建和操作员的相同的字段,只需要第二个参数和IG第一名。也就是说,

/api/v1/item/?name__contains=hello&name__contains=world 

回报资源,其名称字段包含“世界”而不是那些名称字段同时包含“你好”和“世界”。

我知道如何直接在Django做到这一点:

Item.objects.filter(name__contains='hello').filter(name__contains='world') 

但是我怎么构建这样一个查询在tastypie的网址是什么?

回答

0

我在下面使用。它会给你支持name__contains=hello,world。你也可以做否定name__contains!=foo

def build_filters(self, filters=None): 

    """ 
    Adds support for negation filtering 
    """ 
    if not filters: 
     return filters 

    applicable_filters = {} 
    self.filters = filters 

    # Normal filtering 
    filter_params = dict([(x, filters[x]) for x in filter(lambda x: not x.endswith('!'), filters)]) 
    applicable_filters['filter'] = super(MainBaseResource, self).build_filters(filter_params) 

    # Exclude filtering 
    exclude_params = dict([(x[:-1], filters[x]) for x in filter(lambda x: x.endswith('!'), filters)]) 
    applicable_filters['exclude'] = super(MainBaseResource, self).build_filters(exclude_params) 

    return applicable_filters 

def apply_filters(self, request, applicable_filters): 

    """ 
    Adds support for: 
    1. negation filtering: value_date__year!=2013 
    2. multiple filtering value_date__year=2013,2012 
    """ 

    from django.db.models import Q 
    import operator 
    from types import * 

    objects = self.get_object_list(request) 

    f = applicable_filters.get('filter') 

    if f: 
     # Q Filters for multiple values (1,2,3 etc) 
     q_filters = [] 
     for key, val in f.iteritems(): 
      string = str(val) 
      if ',' in string: 
       for excl_filter in string.split(','): 
        q_filters.append((key, excl_filter)) 

     q_list = [Q(x) for x in q_filters] 
     for x in q_filters: 
      try: 
       del f[x[0]] 
      except: 
       pass 
     if q_list: 
      objects = objects.filter(reduce(operator.or_, q_list), **f) 
     else: 
      objects = objects.filter(**f) 

    e = applicable_filters.get('exclude') 
    if e: 
     objects = objects.exclude(**e) 
    return objects 
相关问题