2013-01-04 25 views
6

काफी सरल उदाहरण - मैं Django कोड है कि एक क्वेरीसमूह साथ शुरू होता है का एक सा है ...किस बिंदु पर अपवाद जब Django के ORM का उपयोग कर उठाया जाता है

queryset = MyModel.objects.all() 

बाद में उस पर विभिन्न छानने करता है, कुछ विन्यास पर निर्भर करता है विकल्प ...

if something: 
    queryset = self.queryset.filter(foo=some_foo) 

if another_thing: 
    queryset = self.queryset.filter(bar=some_bar) 

और अंत में यह देखने करता है ...

try: 
    obj = queryset.get() 
except ObjectDoesNotExist: 
    raise ValidationError('Does not exist') 

अब, हो फ़िल्टरिंग की लचीली तरीके के कारण होने पर, यह संभव है कि some_foo या some_bar चर सही प्रकार के नहीं हो सकते हैं (उदाहरण के लिए। हम एक पूर्णांक स्ट्रिंग के साथ एक पूर्णांक फ़ील्ड के खिलाफ फ़िल्टर करने का प्रयास कर सकते हैं।) इसलिए इस कोड के लिए TypeError या ValueError बढ़ाने के लिए यह संभव है।

यह ठीक है, और मैं उचित तरीके से संभाल सकता हूं, लेकिन ओआरएम अनुबंध से मुझे क्या स्पष्ट नहीं है, पर मुझे उन अपवादों को उठाने की उम्मीद करनी चाहिए।

  • यह .filter() बयान पर पाए जाते हैं जाएगा? ...
  • ... या .get() बयान पर? ...
  • ... या underspecified में है, और मैं इसे के रूप में करने में सक्षम संभाल या तो हो सकता है? (उदाहरण के लिए शायद डेटाबेस बैकएंड के कार्यान्वयन पर निर्भर करता है?)
+0

शायद मुझे कुछ याद आ रहा है लेकिन मुझे पूछने की ज़रूरत है: आप क्वेरीसेट पर क्यों कॉल कर रहे हैं? फ़िल्टर() और प्राप्त करें() के पास अलग-अलग उद्देश्य हैं और वे दोनों एक क्वेरी करते हैं। और फ़िल्टर() पहला प्रश्न पूछताछ है -> फ़िल्टरिंग के दौरान टाइप/वैल्यू त्रुटि उठाई जाएगी। आप प्राप्त नहीं करेंगे() –

+0

नोट: ठीक है, मैं इस विशेष मामले में देख सकता हूं कि यह '.get()' कथन (जो मुझे अपेक्षित है) द्वारा उठाया गया प्रतीत होता है लेकिन यह स्पष्ट नहीं है कि मैं सुरक्षित रूप से सुरक्षित हो सकता हूं इस व्यवहार पर लगातार निर्भर रहें। –

+0

@ सैमुलेमैटीज़ुज़ो फ़िल्टर विवरणों को जंजीर किया जा सकता है। अंतिम '.get()' वह बिट है जो क्वेरी को दिए गए एक ऑब्जेक्ट की लुकअप करता है। –

उत्तर

1

मूल सवाल का जवाब करने के लिए, एक FieldError और ValueError, फिल्टर करने के लिए फोन पर उठाया जाता है जब एक नया क्वेरीसमूह बनाया गया है:

>>> a = Account.objects.all() 
>>> a = a.filter(id=3) 
>>> a = a.filter(no_exist=3) 
<snip> 
FieldError: Cannot resolve keyword 'no_exist' into field. Choices are: active, created_on, group, id, ... 

>>> a = Account.objects.all() 
>>> a = a.filter(id='abc') 
ValueError: invalid literal for int() with base 10: 'abc' 

मैं यह भी जोड़ूंगा कि यह पैटर्न मुझे भ्रामक लगता है, उस filter में आमतौर पर एक के बजाय get के साथ मॉडल की एक सूची/पुनरावर्तनीय लौटने के लिए उपयोग किया जाता है। स्पष्टता और अपवादों की आसान हैंडलिंग के लिए, मैं इस पैटर्न सुझाव देंगे:

kwargs = {} 
if something: 
    kwargs['foo'] = some_foo 
if another_thing: 
    kwargs['bar'] = some_bar 

# handle if kwargs is empty 
try: 
    obj = MyModel.objects.get(**kwargs) 
except (FieldError, ValueError, ObjectDoesNotExist): 
    raise ValidationError('Does not exist') 

अन्य अतिरिक्त लाभ यह है कि, IIRC, क्लोनिंग क्वेरीसमूहों का काम अपेक्षाकृत महंगा है, ताकि आप उस भूमि के ऊपर ध्यान न दें, जबकि कम से कोड क्लीनर बनाने के साथ ही एक ही समय। अपने प्रश्न पर वापस जाकर, इस पैटर्न के साथ कोई सवाल नहीं है जहां अपवाद उठाया जाएगा।

+0

'kwargs' पैटर्न शायद अच्छा है। 'FieldError' अपवाद (गलत फ़ील्ड नाम) 'TypeError' (फ़िल्टर में दिए गए गलत प्रकार) के लिए थोड़ा अलग मामला है। पूर्व तुरंत प्रकट होता प्रतीत होता है, लेकिन बाद में ऐसा प्रतीत होता है जब लुकअप वास्तव में बनाया जाता है। फिर भी, मैं जवाब स्वीकार करूंगा क्योंकि मुझे लगता है कि क्वार पैटर्न अस्पष्टता से निपटने का सही तरीका है। –