2015-01-01 9 views
11

में 404 कैसे मैं विशेष रूप से एक अद्वितीय बाधा निम्नलिखित कोड में 404 में विफल रहा है पकड़ने है, मैं जानता हूँ कि मैं में कुछ जोड़ने के लिए (यहाँ?) अनुभागकैसे पकड़ है एक 'अद्वितीय बाधा विफल' Django

try: 
    q = AnswerModel(user=user, yes_question=question_model) 
    q.save() 
except (here?): 
    return HttpResponseRedirect('/user/already_exists') 
+0

क्या आपने कोशिश की * नहीं * इसे पकड़ने की कोशिश की है ताकि आप जान सकें कि वास्तव में यह क्या है? –

+0

निश्चित रूप से त्रुटि, अब मैं अद्वितीय बाधा त्रुटि को पकड़ना चाहता हूं ताकि मैं उपयोगकर्ता को पहले ही उत्तर दे सकूं –

+0

ठीक है, इसलिए जब से आप जानते हैं कि यह क्या है, इसे 'छोड़कर' खंड में रखें। –

उत्तर

18
from django.db import IntegrityError 

except IntegrityError: 

यही आपको चाहिए।

@mbrochh के लिए संपादित:

from django.db import IntegrityError 

except IntegrityError as e: 
    if 'unique constraint' in e.message: # or e.args[0] from Django 1.10 
     #do something 

हाँ, आप और अधिक सटीक हो सकता है लेकिन सवाल मामले में UNIQUE failed अत्यधिक संभावना है।

+0

यह पर्याप्त नहीं है क्योंकि यह केवल विशिष्ट बाधाओं से अधिक पकड़ता है। – mbrochh

+0

मैंने आपके लिए अपना जवाब संपादित कर लिया है। – torm

+0

यह अभी भी एक बुरा समाधान है क्योंकि हम नहीं जानते कि वे संदेश कभी भी बदल जाएंगे या नहीं। त्रुटि कोड के लिए जांच एक बेहतर तरीका होगा। – mbrochh

0

आमतौर पर "क्षमा मांगना" सिद्धांत प्रोग्रामिंग में एक अच्छा अभ्यास है लेकिन इस विशेष मामले में, मैं इसकी अनुशंसा नहीं करता।

आप जो अपवाद ढूंढ रहे हैं वह IntegrityError है। आप आसानी से कोशिश कर सकते थे कि कोशिश-पकड़ ब्लॉक को हटाकर और उस अपवाद को मजबूर कर स्वयं को बाहर निकालें। ट्रेसबैक अपवाद वर्ग दिखाता है।

समस्या यह है कि कई प्रकार की अखंडता त्रुटियां हैं, इसलिए आपके प्रयास-पकड़ ब्लॉक के अंदर आपको यह देखने के लिए if ex.pgcode == 23505 जैसे कुछ की जांच करनी होगी कि यह वास्तव में एक अद्वितीय बाधा त्रुटि है या नहीं। इसका उत्तर यहां दिया गया है: IntegrityError: distinguish between unique constraint and not null violations

यह खराब हो जाता है: प्रत्येक ओआरएम में अलग-अलग त्रुटि कोड होते हैं, फ़ील्ड का नाम pgcode नहीं होगा लेकिन कुछ और कुछ ओआरएम अद्वितीय बाधाओं को नहीं फेंकते हैं। तो यदि आप एक पुन: प्रयोज्य ऐप बना रहे हैं या यदि आप एक ओआरएम का उपयोग कर रहे हैं जो (जैसे MySQL) बेकार है या यदि आप सुनिश्चित नहीं हैं कि भविष्य में कुछ समय में आप अपने प्रोजेक्ट का डेटाबेस बदल देंगे, तो आपको यह नहीं करना चाहिए!

बेहतर तरीका केवल कोशिश-पकड़ ब्लॉक को हटा रहा है और यह जांचने से पहले कि ऑब्जेक्ट पहले ही डेटाबेस में है या नहीं।

मुझे नहीं पता कि आपके मामले में कौन सा क्षेत्र अद्वितीय है, इसलिए मुझे लगता है कि यह user फ़ील्ड है। आपका कोड कुछ इस तरह दिखेगा:

answers = AnswerModel.objects.filter(user=user) 
if answers: 
    return HttpResponseRedirect('/user/already_exists') 
obj = AnswerModel.objects.create(user=user, yes_question=question_model) 
... 

आप एक संयुक्त अद्वितीय बाधा के साथ काम कर रहे हैं, तो पहली पंक्ति इस होगा:

answers = AnswerModel.objects.filter(user=user, yes_question=question_model) 
2

IMHO, मैं get_or_create द्वारा इस स्थिति को हल करने की सिफारिश करेंगे()।

new_obj, created = AnswerModel.objects.get_or_create(user=user, yes_question=question_model) 
if created: 
    do_something_for_new_object(new_obj) 
else: 
    logging.error("Duplicated item.") 
    return
संबंधित मुद्दे