Reputation: 4034
I am having trouble with my 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
In django BooleanField is always set to blank=True due to browsers don't send unchecked checkbox in POST data.
ModelForm sets model field to False in this case. When using DRF ModelSerializer, generated BooleanField is created with required=False, and when the field is not present in data, passed to serializer, model field is set to None and raises IntegrityError when saving model.
Should I explicitly specify BooleanField(default=False) in my ModelSerializer, or I am missing something? I would expect ModelSerializer to behave similar to ModelForm - set value to False when it is not present, which is equal to generating BooleanField with default=False automatically.
I think getting IntegrityError for default behaviour is not what expected, maybe I should submit a bug?
Upvotes: 1
Views: 1743
Reputation: 2753
This was a bug in older versions of Django Rest Framework https://github.com/encode/django-rest-framework/issues/1004 but seems to be solved some time ago, probably you need to explicitly make it required in the serializer like:
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},
}
Or what @bear-brown says is usually the best practice.
Upvotes: 0
Reputation:
When you use models.BooleanField it usually need to check is value True or not, so i think best practices always set default
value for it. And set the default in the models class, for example in your case:
class Recall(models.Model):
thermal_step = models.BooleanField(default=False)
have_inventory = models.BooleanField(default=False)
have_adverse = models.BooleanField(default=True)
Upvotes: 1