2012-03-12 10 views
18

क्या डिफ़ॉल्ट रूप से कोई निषेध फ़िल्टर उपलब्ध है। विचार यह है कि आप Django ORM में निम्न कार्य कर सकते हैं:Tastypie Negation फ़िल्टर

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' द्वारा (इसलिए "बराबर_ _ बराबर" के साथ)। कृपया ध्यान रखें कि Django किसी भी तरह से आपको 'फ़ील्ड! = वैल्यू' को तर्क के रूप में पारित करने की अनुमति दे सकता है, लेकिन इसके परिणामस्वरूप बूलियन मान आगे पारित हो जाएगा (या 'नेमर्रॉ'' यदि 'फ़ील्ड' परिभाषित चर नहीं है)। या मैं गलत हूं और Django उदाहरण के रूप में ऑपरेटर अधिभार प्रदर्शन करता है। क्वेरी बिल्डर के मामले में web2py करता है? – Tadeck

उत्तर

27

दुर्भाग्यवश ऐसा नहीं है।

समस्या यह है कि Tastypie's ModelResource क्लास केवल QuerySet के फ़िल्टर() विधि का उपयोग करती है, यानी यह बाहर नहीं है() जिसे नकारात्मक फ़िल्टर के लिए उपयोग किया जाना चाहिए। कोई फ़िल्टर() फ़ील्ड लुकअप नहीं है जिसका मतलब अस्वीकरण होगा। वैध लुकअप (इस 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" वाले फ़िल्टर अलग करें। फिर आपको पहले समूह को() और बाकी को फ़िल्टर करने के लिए पास करना चाहिए()।

कुछ की तरह:

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

नकारात्मक_फिल्टर में फ़िल्टर की कुंजी "field__not_eq" नहीं होनी चाहिए, लेकिन "field__exact", इसलिए Django ORM मॉड्यूल इसके साथ सौदा कर सकता है। इसके अलावा, build_filters को अधिलेखित किया जाना चाहिए ताकि "__not_eq" Tastypie द्वारा रिश्ते के रूप में नहीं देखा जा सके। – Wilerson

2

मैं इस के लिए एक बग खोला और यहाँ एक सरल उपाय प्रदान की है: https://github.com/toastdriven/django-tastypie/issues/524

यह शायद जोड़ने के लिए अच्छे होगा '!' क्षेत्र नाम के रूप में आप अपने प्रश्न में किया है के अंत में चरित्र ...

6

कोड में परिवर्तन के बिना यह करने के लिए एक और तरीका है Gorneau के ऊपर जवाब पर साथ inverse matching

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

मैं बाहर निकालने के() कुछ मान से बचने के लिए इस्तेमाल करते हैं।

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