Tastypie Negation Filter

mik*_*725 19 api django tastypie

默认情况下是否有可用的否定过滤器.想法是你可以在django ORM中执行以下操作:

model.objects.filter(field!=value)
Run Code Online (Sandbox Code Playgroud)

如果可能的话,我怎么能在tastypie中做到这一点.我试过了:

someapi.com/resource/pk/?field__not=value
someapi.com/resource/pk/?field__!=value
someapi.com/resource/pk/?field!=value
Run Code Online (Sandbox Code Playgroud)

而且他们都给了我错误.

kgr*_*kgr 28

不幸的是没有.

问题是Tastypie的ModelResource类仅使用QuerySet的filter()方法,即它不使用应该用于负过滤器的exclude().虽然没有filter()字段查找意味着否定.有效的查找是(在此SO帖子之后):

exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
year
month
day
week_day
isnull
search
regex
iregex
Run Code Online (Sandbox Code Playgroud)

但是,实现对"__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)
Run Code Online (Sandbox Code Playgroud)

而不是默认值:

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)
Run Code Online (Sandbox Code Playgroud)

应该允许以下语法:

someapi.com/resource/pk/?field__not_eq=value
Run Code Online (Sandbox Code Playgroud)

我没有测试过.它也许可以用更优雅的方式编写,但应该让你去:)


Gou*_*eau 6

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

http://HOST/api/v1/resource/?format=json&thing__iregex=^((?!notThis).)*$
Run Code Online (Sandbox Code Playgroud)