2015-11-02 14 views
9

में सत्यापन त्रुटि को उठाते समय त्रुटि कोड निर्दिष्ट करने के लिए कैसे करें मेरे पास एक एपीआई एंडपॉइंट है जो उपयोगकर्ताओं को खाता पंजीकृत करने की अनुमति देता है। मैं एक डुप्लिकेट उपयोगकर्ता नाम के लिए 400 के बजाय HTTP 40 9 वापस करना चाहता हूं।Django REST Framework serializer

from django.contrib.auth.models import User 
from rest_framework.serializers import ModelSerializer 

class UserSerializer(ModelSerializer): 
    username = CharField() 

    def validate_username(self, value): 
     if User.objects.filter(username=value).exists(): 
      raise NameDuplicationError() 
     return value 


class NameDuplicationError(APIException): 
    status_code = status.HTTP_409_CONFLICT 
    default_detail = u'Duplicate Username' 

जब त्रुटि शुरू हो रहा है, प्रतिक्रिया है:: {"detail":"Duplicate Username"}

यहाँ मेरी serializer है। मुझे एहसास हुआ कि अगर मैं APIException subclass, detailusername के बजाय उपयोग किया जाता है।

मैं इस प्रतिक्रिया के बजाय {"username":"Duplicate Username"}

करना चाहते हैं या मैं एक स्थिति कोड जब एक ValidationError को ऊपर उठाने निर्दिष्ट करने के लिए करना चाहते हैं:

def validate_username(self, value): 
    if User.objects.filter(username=value).exists(): 
     raise serializers.ValidationError('Duplicate Username', 
              status_code=status.HTTP_409_CONFLICT) 
    return value 

लेकिन जैसे ValidationError केवल रिटर्न 400

यह काम नहीं करता

क्या इसे पूरा करने का कोई और तरीका है?

उत्तर

13

आप की तरह अलग अलग अपवाद बढ़ा सकते हैं:

from rest_framework.exceptions import APIException 
from django.utils.encoding import force_text 
from rest_framework import status 


class CustomValidation(APIException): 
    status_code = status.HTTP_500_INTERNAL_SERVER_ERROR 
    default_detail = 'A server error occurred.' 

    def __init__(self, detail, field, status_code): 
     if status_code is not None:self.status_code = status_code 
     if detail is not None: 
      self.detail = {field: force_text(detail)} 
     else: self.detail = {'detail': force_text(self.default_detail)} 

आप की तरह अपने serializer में इस का उपयोग कर सकते हैं:

raise CustomValidation('Duplicate Username','username', status_code=status.HTTP_409_CONFLICT) 

या

raise CustomValidation('Access denied','username', status_code=status.HTTP_403_FORBIDDEN) 
3

उपयोग Django-आराम-ढांचे कस्टम अपवाद संचालक http://www.django-rest-framework.org/api-guide/exceptions/

def custom_exception_handler(exc, context=None): 
    response = exception_handler(exc, context) 
    if response is not None: 
     if response.data['detail'] == 'Duplicate Username': 
      response.data['username'] = response.data.pop('detail') 
     response.status_code = status.HTTP_409_CONFLICT 
    return response 
+0

ग्रेट, यह काम करता है। यदि मैं अलग-अलग विचारों के लिए अपवाद को कस्टमाइज़ करना चाहता हूं तो यह फ़ंक्शन बहुत जटिल हो जाएगा। चूंकि विचारों की संख्या बढ़ जाती है, यह कार्य भी बढ़ेगा। मुझे आश्चर्य है कि एक स्केल करने योग्य समाधान है या नहीं। – Cheng

+0

क्या आप 'विस्तार' को ओवरराइड करना चाहते हैं? –

+0

मेरा मतलब है कि अगर 3 अपवाद हैं जिन्हें मैं ओवरराइड करना चाहता हूं, तो मेरे पास 'custom_exception_handler' में if..elif..elif संरचना होगी। जितना अधिक अपवाद मैं अनुकूलित करना चाहता हूं, उतना अधिक ifs मुझे इस विधि में लिखना होगा। साथ ही, मुझे यह याद रखना होगा कि यदि शाखा जिम्मेदार है जिसके लिए दृश्य HTTP गतिविधि है। यह लाइन के नीचे एक असली मुद्दा हो सकता है। – Cheng