ModelSerializer中的DRF BooleanField导致IntegrityError

时间:2017-10-10 19:49:52

标签: django django-rest-framework

我的ModelSerializer出现问题

class Recall(models.Model):
    thermal_step = models.BooleanField()
    have_inventory = models.BooleanField()
    have_adverse = models.BooleanField()


class OrderRecallSerializer(serializers.ModelSerializer):
    class Meta:
        model = Recall
        fields = ['thermal_step', 'have_inventory', 'have_adverse']

s = OrderRecallSerializer(data={})
s.is_valid()
>>> True
s.save()
>>> django.db.utils.IntegrityError: null value in column 
"thermal_step" violates not-null constraint

在django中,由于浏览器未在POST数据中发送未选中的复选框,因此BooleanField始终设置为blank = True。

在这种情况下,ModelForm将模型字段设置为False。使用DRF ModelSerializer时,生成的BooleanField使用required = False创建,当数据中不存在该字段时,传递给serializer,模型字段设置为None,并在保存模型时引发IntegrityError。

我应该在ModelSerializer中明确指定BooleanField(default = False),还是我遗漏了什么?我希望ModelSerializer的行为类似于ModelForm - 当它不存在时将值设置为False,这相当于自动生成BooleanField并使用default = False。

我认为获取IntegrityError的默认行为不是预期的,也许我应该提交错误?

2 个答案:

答案 0 :(得分:1)

使用models.BooleanField时,通常需要检查值是否为True,因此我认为最佳做法始终为其设置default值。并在模型类中设置default,例如在您的情况下:

class Recall(models.Model):
    thermal_step = models.BooleanField(default=False)
    have_inventory = models.BooleanField(default=False)
    have_adverse = models.BooleanField(default=True)

答案 1 :(得分:0)

这是旧版本的Django Rest Framework https://github.com/encode/django-rest-framework/issues/1004中的一个错误,但似乎很久以前就已经解决了,可能你需要在序列化程序中明确地要求它,如:

class OrderRecallSerializer(serializers.ModelSerializer):
    class Meta:
        model = Recall
        fields = ['thermal_step', 'have_inventory', 'have_adverse']
        extra_kwargs = {
          'thermal_step': {'required': True, 'allow_null': False},
          'have_inventory': {'required': True, 'allow_null': False},
          'have_adverse': {'required': True, 'allow_null': False},
        }

或者@ bear-brown所说的通常是最好的做法。