2015-03-25 19 views
8

मैं की तरहदबाने Django बाकी ढांचे में त्रुटि "क्षेत्र अद्वितीय होना चाहिए"

class MyModel(models.Model): 
    uuid = models.CharField(max_length=40, unique=True) 

और एक serializer

class MyModelSerializer(serializers.ModelSerializer):  
    class Meta: 
     model = MyModel 
    fields = ('uuid') 

और मैं MyModel वस्तु के साथ JSON प्राप्त करना चाहते हैं, लेकिन यह हो सकता है एक मॉडल मौजूदा वस्तुओं तो, जब मैं मौजूदा वस्तु के बारे में डेटा के साथ serializer.is_valid() का उपयोग यह मुझे एक त्रुटि देता है:

for record in request['records']: 
    # request - body of JSON request, 
    # 'records' - array of records I want to add or update 

    serializer = MyModelSerializer(data=record) 
    if serializer.is_valid(): 
     # Do stuff 
     serializer.save() 

त्रुटि:

{"uuid":["This field must be unique."]} 

वहाँ एक रास्ता नए और मौजूदा वस्तुओं के लिए व्यवहार को अलग करने के है? विशेष रूप से, मैं नया MyModel ऑब्जेक्ट बनाना चाहता हूं यदि यह अभी तक डेटाबेस नहीं है और मौजूद होने पर मौजूदा MyModel ऑब्जेक्ट अपडेट करें।

+0

आप कोड आप serializer के साथ काम करने के लिए प्रयोग कर रहे हैं (आमतौर पर जोड़ सकते हैं देखें) प्रश्न के लिए? –

+0

जोड़ा गया, लेकिन यह बेकार जानकारी है क्योंकि मैंने पहले से ही वर्णन किया है - समस्या is_valid() फ़ंक्शन में है। –

+0

क्या आप अपना पूरा एपीआई व्यू कोड जोड़ सकते हैं? शायद आप एक उदाहरण बनाने और अद्यतन करने के लिए एक POST अनुरोध का उपयोग कर रहे हैं? – Fiver

उत्तर

2

आप मूल रूप से नए इंस्टेंस बनाने और POST अनुरोध का उपयोग कर मौजूदा उदाहरणों को अपडेट करने की कोशिश करके अपने आरईएसटी एपीआई के एक एकल प्रविष्टि बिंदु को अधिभारित कर रहे हैं। इसके अलावा, ऐसा लगता है कि आप एकल POST अनुरोध के साथ-साथ कई उदाहरणों को बनाने और अपडेट करने का प्रयास कर रहे हैं।

Django REST Framework (DRF) को केवल नए उदाहरण बनाने के लिए एक POST अनुरोध की उम्मीद है। इसलिए, मौजूदा उदाहरण रिकॉर्ड भेजना uuid फ़ील्ड के लिए एक अद्वितीय बाधा उल्लंघन को ट्रिगर करता है क्योंकि डीआरएफ उस रिकॉर्ड को एक नए इंस्टेंस के रूप में बनाने का प्रयास करता है, क्योंकि मौजूदा इंस्टेंस में पहले से ही यूयूआईडी वैल्यू है।

आपके आरईएसटी एपीआई को अधिक "रीस्टफुल" बनाने का एक समाधान क्रमशः पोस्ट और पुट अनुरोधों में रिकॉर्ड बनाने और अद्यतन करने के लिए अलग होगा। यह स्पष्ट नहीं है कि आप generic API views provided by DRF का उपयोग कर रहे हैं, लेकिन आप नए उदाहरणों के लिए CreateAPIView का उपयोग कर सकते हैं, फिर PUT और/या मौजूदा उदाहरणों को पैच करने के लिए एक अलग UpdateAPIView बनाएं। इससे भी बेहतर आप जेनेरिक विचार ListCreateAPIView और RetrieveUpdateAPIView का उपयोग करके इन दोनों एंडपॉइंट्स के लिए जीईटी के माध्यम से पुनर्प्राप्ति की अनुमति दे सकते हैं।

अंत में, थोक अनुरोधों को संभालने के लिए (यानी एक अनुरोध में बहु-उदाहरण) आप या तो अंतर्निहित दृश्य विधियों को ओवरराइड कर सकते हैं या किसी तृतीय-पक्ष पैकेज जैसे django-rest-framework-bulk का उपयोग कर सकते हैं।

2

मेरे पास ऐसी स्थिति थी जहां मेरे पास एक गहरी बनाने की विधि थी, अंत बिंदु के ऊपर पदानुक्रम के 2 स्तरों के साथ, यह महत्वपूर्ण था कि सभी मॉडल बेवकूफ थे।

मैं धारावाहिक में सत्यापन को ओवरराइड करता हूं, और इसे हाथ से बना देता हूं।

ऐसा नहीं है कि आप शीर्ष (अन्यथा वैलिडेटर चलाएं नहीं किया जाएगा) पर वर्ग के लिए क्षेत्र को जोड़ने के लिए महत्वपूर्ण है

class ParticipantSerializer(serializers.HyperlinkedModelSerializer): 

    device = DeviceSerializer(required=False) 
    uuid = serializers.CharField() 

    def validate_uuid(self, value): 
     if value is not None and isinstance(value, basestring) and len(value) < 256: 
      return value 
     else: 
      if value is not None: 
       raise serializers.ValidationError("UUID can't be none") 
      elif isinstance(value, basestring): 
       raise serializers.ValidationError("UUID must be a string") 
      elif len(value) < 256: 
       raise serializers.ValidationError("UUID must be below 256 characters") 
      else: 
       raise serializers.ValidationError("UUID has failed validation") 

    class Meta: 
     model = Participant 
     fields = ("uuid", "platform", "device") 
+0

के साथ पहले सामान के लिए जोड़ा गया कस्टम सत्यापन विधि मेरे लिए आवश्यक नहीं था। बस 'serializers.harfield()' को परिभाषित करने से समस्या ठीक हो गई। मुझे लगता है कि ऐसा इसलिए है क्योंकि यह पूरी तरह से 'मॉडल को छोड़ देता है।CharField 'सत्यापन और इसके बजाय' serializers.CharField' सत्यापन का उपयोग करता है। 'serializers.CharField' में 'अद्वितीय' विकल्प भी नहीं है और इसमें डिफ़ॉल्ट रूप से कोई वैधता शामिल नहीं है। http://www.django-rest-framework.org/api-guide/fields/ – morningstar

संबंधित मुद्दे