【问题标题】:Django serializer is_valid() returns True incorrectlyDjango 序列化程序 is_valid() 错误地返回 True
【发布时间】:2016-03-25 20:38:28
【问题描述】:

我遇到了一个问题,即使序列化中提供的数据不完整,我的 serializer.is_valid() 方法仍返回 true。我有一个看起来像这样的简单模型:

class Dummy(models.Model):
    first_name = models.TextField(max_length=128)
    last_name = models.TextField(max_length=128)
    organization = models.TextField(max_length=128)
    email = models.EmailField()
    can_contact = models.BooleanField()

为此我创建了以下序列化程序:

class DummySerializer(serializers.ModelSerializer):
    class Meta:
        model = Dummy
        fields = ('first_name', 'last_name', 'organization', 'email',
                'can_contact',)

如果我再运行这个测试(注意输入序列化中缺少can_contact):

>>> serializer = DummySerializer(data = {'first_name': 'foo', 'last_name': 'bar', 'organization': 'quux inc', 'email': 'foo@example.com'})
>>> serializer.is_valid()
True

如果我要尝试保存序列化程序,我会遇到约束失败:

django.db.utils.IntegrityError: NOT NULL constraint failed: demo_dummy.can_contact

它似乎专门是 BooleanField;任何其他字段都将被正确识别为缺失。序列化程序出了什么问题,除了自己手动输入验证之外,我该怎么办?

感谢您的宝贵时间!

【问题讨论】:

    标签: django serialization


    【解决方案1】:

    不知道为什么它会这样工作,我知道你想避免手动输入验证,但这是一种解决方法:

    根据您拥有的 django rest 框架的版本,将以下内容添加到您的序列化程序中:

    DRF v2:

    def validate_can_contact(self, attrs, source):
        if source in attrs:
            return attrs
        else:
            raise serializers.ValidationError("Field Missing")
    

    DRF v3:

    def validate_can_contact(self, value):
        if 'can_contact' in value:
            return value
        else:
            raise serializers.ValidationError("Field Missing")
    

    【讨论】:

    • 感谢您的建议;我试过了,但没有一个版本的方法被调用。我可以为其他字段类型创建自定义验证器,例如validate_first_name 将被调用(它使用 v3 调用约定)。但是validate_can_contact 没有被调用。
    • 有趣...我尝试将blank=False 添加到模型规范中(所以can_contact = BooleanField(blank=False),然后验证器被调用,但value 参数是False。不应该是None 缺少字段?
    【解决方案2】:

    来自 Django Boolean Field Docs:

      The default value of BooleanField is None when Field.default isn’t defined.
    

    给出的错误是:

      django.db.utils.IntegrityError: NOT NULL constraint failed: demo_dummy.can_contact
    

    DRF 模型序列化程序正在映射来自 Django 模型的字段/属性。 所以我认为你必须为布尔字段声明一些默认值 True 或 False 或者 如果您想接受 Null 值,则将布尔字段更改为 NullBooleanField

    【讨论】:

    • 将其更改为 NullBooleanField 允许 save 方法正常工作,但当字段丢失时它仍然无法抱怨。如果can_contact 不在表单数据中,我希望is_valid() 返回false。
    猜你喜欢
    • 2018-10-13
    • 2019-03-22
    • 1970-01-01
    • 2017-06-06
    • 2013-12-26
    • 2015-09-28
    • 2022-12-19
    • 1970-01-01
    • 2015-12-22
    相关资源
    最近更新 更多