2012-03-12 73 views
18

默认情况下是否有可用的否定过滤器。我们的想法是,你可以做在Django的ORM如下:Tastypie否定过滤器

model.objects.filter(field!=value) 

我怎样才能做到这一点在tastypie如果这甚至有可能。我试过:

someapi.com/resource/pk/?field__not=value 
someapi.com/resource/pk/?field__!=value 
someapi.com/resource/pk/?field!=value 

而且他们都给了我错误。

+1

在某些情况下,你有这样的一些过滤器来取代它的功能:'field__not = null'可以用'field__isnull = FALSE'被替换,“_not更大than_”可以更换?通过'?field__lte = x'(所以用“_less than equal_”)。另外请记住,Django可能以某种方式允许您将'field!= value'作为参数传递,但会导致布尔值被进一步传递(如果'field'不是定义的变量,则返回'NameError')。还是我错了,Django执行运算符重载,例如。 web2py确实在查询生成器的情况下? – Tadeck 2012-10-24 16:23:46

回答

27

不幸的是没有。

问题是Tastypie的ModelResource类只使用QuerySet的filter()方法,即它不使用exclude(),它应该用于负滤镜。没有过滤器()字段查找,这将意味着否定。有效的查找(这SO post后):

exact 
iexact 
contains 
icontains 
in 
gt 
gte 
lt 
lte 
startswith 
istartswith 
endswith 
iendswith 
range 
year 
month 
day 
week_day 
isnull 
search 
regex 
iregex 

但是它不应该这么难实现的东西,如“__not_eq”的支持。所有你需要做的就是修改apply_filters()方法,并用其余的“__not_eq”来分隔过滤器。然后你应该通过第一个组排除(),其余的通过filter()。

喜欢的东西:

def apply_filters(self, request, applicable_filters): 
    """ 
    An ORM-specific implementation of ``apply_filters``. 

    The default simply applies the ``applicable_filters`` as ``**kwargs``, 
    but should make it possible to do more advanced things. 
    """ 
    positive_filters = {} 
    negative_filters = {} 
    for lookup in applicable_filters.keys(): 
     if lookup.endswith('__not_eq'): 
      negative_filters[ lookup ] = applicable_filters[ lookup ] 
     else: 
      positive_filters[ lookup ] = applicable_filters[ lookup ] 

    return self.get_object_list(request).filter(**positive_filters).exclude(**negative_filters) 

而不是默认的:

def apply_filters(self, request, applicable_filters): 
    """ 
    An ORM-specific implementation of ``apply_filters``. 

    The default simply applies the ``applicable_filters`` as ``**kwargs``, 
    but should make it possible to do more advanced things. 
    """ 
    return self.get_object_list(request).filter(**applicable_filters) 

应该允许的语法如下:

someapi.com/resource/pk/?field__not_eq=value 

我没有测试它。这也许可以写在太更优雅的方式,但应该让你去:)

+0

negative_filters中过滤器的关键字不应该是“field__not_eq”,而应该是“field__exact”,因此Django ORM模块可能会处理它。 另外,build_filters必须被覆盖,所以“__not_eq”不会被Tastypie视为关系。 – Wilerson 2012-05-04 17:07:47

6

另一种方式来做到这一点无需更改代码是对Gorneau的以上回答使用iregex与inverse matching

http://HOST/api/v1/resource/?format=json&thing__iregex=^((?!notThis).)*$ 
-1

我用排除(),以避免一些值。例如:

Person.filter(name="Tim").exclude(state="Down");