19

Is there a negation filter available by default. The idea is that you can do the following in the django ORM:

model.objects.filter(field!=value)

How can I do that in tastypie if that is even possible. I tried:

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

And all of them given me errors.

4

5 回答 5

28

不幸的是没有。

问题是 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”将过滤器与其余过滤器分开。然后你应该将第一组传递给 exclude(),其余的传递给 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

我没有测试过。它可能也可以用更优雅的方式编写,但应该让你继续前进:)

于 2012-03-16T21:13:42.950 回答
6

在不更改代码的情况下执行此操作的另一种方法是使用具有反向匹配的 iregex

http://HOST/api/v1/resource/?format=json&thing__iregex=^((?!notThis).)*$
于 2013-09-25T23:32:30.963 回答
2

我为此打开了一个错误并在这里提供了一个简单的解决方案:https ://github.com/toastdriven/django-tastypie/issues/524

添加“!”可能会更好。正如您在问题中所做的那样,字段名称末尾的字符...

于 2012-06-13T14:04:32.060 回答
1

请注意 Gorneau 的上述答案:似乎这仅在您不使用 MySQL 后端时才有效。看:

#1139 - 从正则表达式中得到错误“重复运算符操作数无效”

于 2015-02-14T02:50:55.007 回答
-1

我使用 exclude() 来避免某些值。例如:

Person.filter(name="Tim").exclude(state="Down");
于 2016-02-15T14:26:58.563 回答