2017-08-14 73 views
0

我有這兩個相關的模型時,對NOT NULL列完整性錯誤:Django的REST框架:發佈數據

class EndPoint(TimeStampedModel): 
    name = models.CharField(max_length=100) 
    url = models.CharField(max_length=100) 
    description = models.CharField(max_length=100) 

class Parameter(TimeStampedModel): 
    name = models.CharField(max_length=100) 
    label = models.CharField(max_length=100) 
    required = models.BooleanField() 
    type = models.CharField(max_length=100) 
    format = models.CharField(max_length=100, null = True) 
    endpoint = models.ForeignKey(EndPoint, related_name="parameters",null = True, on_delete=models.CASCADE) 

哪個地圖這些seralizers:

class ParameterRelationSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Parameter 
     fields = ('id', 'name', 'label', 'required','type','format') 

class EndPointSerializer(serializers.ModelSerializer): 
    parameters = ParameterRelationSerializer(many = True, read_only=False) 

    class Meta: 
     model = EndPoint 
     fields = ('id', 'name', 'url', 'description', 'parameters') 

    def create(self, validated_data): 
     parameters = validated_data.pop('parameters') 
     endPoint = EndPoint.objects.create(**validated_data) 
     for parameter_relation in parameters: 
      Parameter.objects.create(endpoint=endPoint, **parameter_relation) 
     return endPoint 

現在,當我嘗試後新的端點與此數據:

{ 
    "url": "http://the.url.com", 
    "name": "Dummy url", 
    "description":"This is a dummy url", 
    "parameters": [ 
     { "name":"dummyparam", "type":"dummy", "label": "dummy_parameter" } 
    ] 
} 

我得到一個500錯誤說這:

IntegrityError at /catalogs/endpoints/ 
null value in column "required" violates not-null constraint 
DETAIL: Failing row contains (6, 2017-08-14 12:01:52.857902+00, 2017-08-14 12:01:52.857984+00, dummyparam, dummy_parameter, null, dummy, null, 6). 

基本上,它抱怨非空'必需'屬性(在參數模型中)丟失,從而導致數據庫錯誤。

我的問題是,這不應該由序列化器驗證程序處理,而不是拋出數據庫異常?事實上,我有另一堆非null屬性在json數據中丟失時觸發驗證錯誤。

回答

1

爲了回答您的具體問題 -

我的問題是,不應該由序列化驗證器 來處理,而不是拋出數據庫異常?事實上,我有另一堆 非空屬性,當在json數據中丟失 時會觸發驗證錯誤。

序列化程序結束時的驗證程序僅在請求數據中存在該密鑰時執行。由於您沒有根據需要傳遞該屬性,因此在序列化程序結束時不會調用驗證器。

你也應該告訴你的關於與extra_kwargs的幫助等領域串行如下 -

extra_kwargs = { 
    'required': {'required': True}, 
} 
+0

謝謝,我設法用extra_kwargs來解決它。儘管如此,還是有一些東西沒有達到100%的理解。你說驗證器只有在請求數據中存在該密鑰時纔會運行,但這很奇怪,就像我說的其他字段(例如'label')不可空,並且即使不存在驗證錯誤請求。我想它具體與BooleanFields有關。 –

+1

也許你是對的。我將不得不再看看這個。完成後會立即更新。 –

1

你可以嘗試添加is_valid()

ParameterRelationSerializer 
for parameter_relation in parameters: 
     parameter_relation.update({"endpoint":endPoint}) 
     serializer = ParameterRelationSerializer(data=parameter_relation) 
     if serializer.is_valid(): 
      serializer.save() 

的,如果你需要它,你可以添加加薪驗證exeption:

 serializer.is_valid(raise_exception=True) 
     serializer.save()