2014-09-25 48 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)