umutbozkurt / django-rest-framework-mongoengine

Mongoengine support for Django Rest Framework
MIT License
616 stars 167 forks source link

EmbeddedDocument field in DocumentSerializer can't be set to null #256

Open sebitoelcheater opened 6 years ago

sebitoelcheater commented 6 years ago

I have a Charger document that contains a discount EmbeddedDocumentField. I also have a serializer for Charger.

class Discount(mongoengine.EmbeddedDocument):
    amount = mongoengine.FloatField(default=0)
    start = mongoengine.DateTimeField(default=datetime.datetime.fromtimestamp(0))
    end = mongoengine.DateTimeField(default=datetime.datetime.fromtimestamp(253400999999))

class Charger(Document):
    discount = mongoengine.EmbeddedDocumentField(Discount, null=True, required=False)

class ChargerSerializer(DocumentSerializer):
    class Meta:
        model = Charger
        fields = ('id', 'discount')
        extra_kwargs = {
            'discount': {'required': False, 'allow_null': True}
        }

When I call save on ChargerSerializer with discount set to None, it raises this error

  File "/Users/sebito/Developer/Proyectos/cargoo/cargoo/api/serializers/profile_serializer.py", line 89, in handle_update
    instanced_serializer.save()
  File "/Users/sebito/.virtualenvs/cargoo/lib/python3.6/site-packages/rest_framework/serializers.py", line 209, in save
    self.instance = self.update(self.instance, validated_data)
  File "/Users/sebito/.virtualenvs/cargoo/lib/python3.6/site-packages/rest_framework_mongoengine/serializers.py", line 269, in update
    instance = self.recursive_save(validated_data, instance)
  File "/Users/sebito/.virtualenvs/cargoo/lib/python3.6/site-packages/rest_framework_mongoengine/serializers.py", line 230, in recursive_save
    me_data[key] = field.recursive_save(value)
  File "/Users/sebito/.virtualenvs/cargoo/lib/python3.6/site-packages/rest_framework_mongoengine/serializers.py", line 224, in recursive_save
    for key, value in validated_data.items():
AttributeError: 'NoneType' object has no attribute 'items'

in recursive_save method of DocumentSerializer, it's assumed that validated_data won't be null but it might.

BurkovBA commented 6 years ago

Can you try going with the implicit EmbeddedDocumentSerializer for discount, without creating one of your own? Also, make sure that the versions of libraries are exactly as follows:

django==1.9
djangorestframework==3.3.3
mongoengine==0.9
pymongo==2.7
sebitoelcheater commented 6 years ago

What do you think about this fix? https://github.com/sebitoelcheater/django-rest-framework-mongoengine/commit/16f7bef79af1d9b9db8690e9327e2783fb3629eb

vijesh-venugopal commented 4 years ago

I'm also facing the same issue related to the EmbeddedDocumentSerializer and here the value for EmbeddedDocumentSerializer field is an object of model. It returns the error like above:

AttributeError: 'Modelname' object has no attribute 'items' Any suggestions please.

Package versions: django == 3.0.4 djangorestframework == 3.11.0 mongoengine == 0.19.1 pymongo == 3.10.1 django-rest-framework-mongoengine == 3.4.1