In Django REST framework (2.1.16) I have a model with nullable FK field type
, but POST creation request gives 400 bad request
which says that field is required.
My model is
class Product(Model):
barcode = models.CharField(max_length=13)
type = models.ForeignKey(ProdType, null=True, blank=True)
and serializer is:
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
exclude = ('id')
I've tried to add type
explicitly to serializer like
class ProductSerializer(serializers.ModelSerializer):
type = serializers.PrimaryKeyRelatedField(null=True, source='type')
class Meta:
model = Product
exclude = ('id')
and it has no effect.
From http://django-rest-framework.org/topics/release-notes.html#21x-series I see that there was a bug, but it was fixed in 2.1.7.
How should I change serializer to properly handle my FK field?
Thanks!
UPDATE: from the shell it gives
>>> serializer = ProductSerializer(data={'barcode': 'foo', 'type': None})
>>> print serializer.is_valid()
True
>>>
>>> print serializer.errors
{}
but without type=None:
>>> serializer = ProductSerializer(data={'barcode': 'foo'})
>>> print serializer.is_valid()
False
>>> print serializer.errors
{'type': [u'This field is required.']}
>>> serializer.fields['type']
<rest_framework.relations.PrimaryKeyRelatedField object at 0x22a6cd0>
>>> print serializer.errors
{'type': [u'This field is required.']}
in both cases it gives
>>> serializer.fields['type'].null
True
>>> serializer.fields['type'].__dict__
{'read_only': False, ..., 'parent': <prodcomp.serializers.ProductSerializer object at 0x22a68d0>, ...'_queryset': <mptt.managers.TreeManager object at 0x21bd1d0>, 'required': True,
django rest framework - ForeignKey does not allow null values - Stack Overflow. Stack Overflow for Teams – Start collaborating and sharing organizational knowledge.
to_representation(self, value) method. This method takes the target of the field as the value argument, and should return the representation that should be used to serialize the target. The value argument will typically be a model instance.
Each field in a Form class is responsible not only for validating data, but also for "cleaning" it — normalizing it to a consistent format. — Django documentation. Serializer fields handle converting between primitive values and internal datatypes.
Add the kwarg allow_null
when initializing the serializer:
class ProductSerializer(serializers.ModelSerializer):
type = serializers.PrimaryKeyRelatedField(null=True, source='type', allow_null=True)
As already mentioned in the comment of @gabn88 but I think it warrants its own answer. (Cost me some time because I only read that comment after finding it out by myself.)
See http://www.django-rest-framework.org/api-guide/relations/
I'm not sure what's going on there, we've got coverage for that case and similar cases work fine for me.
Perhaps try dropping into the shell and inspecting the serializer directly.
For example if you instantiate the serializer, what does serializer.fields
return? How about serializer.field['type'].null
? If you pass data to the serializer directly in the shell what results do you get?
For example:
serializer = ProductSerializer(data={'barcode': 'foo', 'type': None})
print serializer.is_valid()
print serializer.errors
If you get some answers to those, update the question and we'll see if we can get it sorted.
Edit
Okay, that explains things better. The 'type' field is nullable, so it may be None
, but it's still a required field. If you want it to be null you have to explicitly set it to None
.
If you really do want to be able to exclude the field when POSTing the data, you can include the required=False
flag on the serializer field.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With