2014-09-25 103 views
1

我的問題是關於Django的REST框架序列化,類型字段Django的REST框架串行驗證字段數據類型

我的串行這麼想的支票!我想我錯過服用點

我的樣品串行測試

class TestSerializer(serializers.Serializer): 

    test_bool = serializers.BooleanField(required=True) 

    class Meta: 
     fields = ('test_bool',) 

測試串行)我的示例代碼

def test_my_test(self): 

    data = {'test_bool': 'bla'} 
    serializer = TestSerializer(data=data) 
    self.assertEquals(serializer.is_valid(), True) 

serializer.is_valid(一定是假的,因爲「test_bool給定值'是str不是布爾值,但實際上serializer.is_valid()是真的!爲什麼這個 !!

感謝您的幫助

回答

5

您的問題的答案是類型轉換。 DRF轉換值使用以下算法爲布爾:

if value in ('true', 't', 'True', '1'): 
    return True 
if value in ('false', 'f', 'False', '0'): 
    return False 
return bool(value) 

當你在最後一行看到,DRF明確轉換值布爾值。從外殼:

>>> bool('bla') 
True 

所以這就是爲什麼你的例子總是返回True。爲了避免這種影響,您需要創建一個自定義字段並指定必要的轉換規則。例如:

from rest_framework import serializers 


class StrictBooleanField(serializers.BooleanField): 
    def from_native(self, value): 
     if value in ('true', 't', 'True', '1'): 
      return True 
     if value in ('false', 'f', 'False', '0'): 
      return False 
     return None 


class TestSerializer(serializers.Serializer): 
    test_bool = StrictBooleanField(required=True) 

    class Meta: 
     fields = ('test_bool',) 
... 

# tests.py 
class TestSerializerTestCase(unittest.TestCase): 
    def test_my_test(self): 
     data = {'test_bool': 'bla'} 
     serializer = TestSerializer(data=data) 

     self.assertFalse(serializer.is_valid()) 
     self.assertDictEqual(
      {'test_bool': [u'This field is required.']}, serializer.errors 
     ) 
+0

感謝ü如此多的亞歷克斯。 – 2014-09-26 09:26:41

0
from django.core.exceptions import ValidationError 

class StrictBooleanField(serializers.BooleanField): 

    def from_native(self, value): 
     if isinstance(value, str): 
      if value in ('true', 't', 'True', '1'): 
       return True 
      if value in ('false', 'f', 'False', '0'): 
       return False 
     if isinstance(value, bool): 
      return bool(value) 
     msg = self.error_messages['invalid'] 
     raise ValidationError(msg) 

我只是改變痘痘的StrictBooleanField類,因此,如果錯誤的數據,給出了布爾,我們會得到無效的錯誤的領域,不是必需的。

1

對於未來的訪問者,from_native方法已在DRF> = 3.0中重命名。從更新日誌:

的from_native(個體經營,價值)和to_native(個體經營,數據) 都換成了更明顯的命名 to_internal_value(個體經營,數據)和to_representation(個體經營,value)方法的名稱。

此外,而不是返回None,你應該調用fail()方法是這樣的:

class StrictBooleanField(serializers.BooleanField): 
    def to_internal_value(self, value): 
     if value in ('true', 't', 'True', '1'): 
      return True 
     if value in ('false', 'f', 'False', '0'): 
      return False 
     self.fail('invalid', input=data)