2012-03-12 110 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");