umutbozkurt/django-rest-framework-mongoengine

DynamicEmbeddedDocument serialization?

Opened this issue · 3 comments

I'm attempting to create a REST service with the following:

class Configuration(mongoengine.DynamicEmbeddedDocument):
    storage = mongoengine.IntField(default=150)
    notify = mongoengine.BooleanField(default=True)

class PolicyConfig(DocumentBase):
    account_id = mongoengine.StringField(required=True)
    policy_id = mongoengine.StringField(required=True)
    configuration = mongoengine.EmbeddedDocumentField(Configuration, default=lambda: Configuration())

I want to use a DynamicEmbeddedDocument because the source of the data may be updated at different times than the server. I need to save any information sent to me instead of throwing errors or ignoring the data. I know I could use a DictField(), but I would like to validate the data that I do know about, at the very least.

What I came up with was this:

class ConfigurationSerializer(serializers.EmbeddedDocumentSerializer, serializers.DynamicDocumentSerializer):
    class Meta:
        model = Configuration
        fields = '__all__'


class PolicyConfigurationSerializer(serializers.DocumentSerializer):
    configuration = ConfigurationSerializer(many=False)

    class Meta:
        model = PolicyConfig
        fields = '__all__'

Things seem to work, but it does feel a bit hacky. Is there a better way to go about this? Is my original set of documents koo-koo?

Thanks!

Hi, @DaytonG.

Thank you for reporting this! I'm scratching my head, cause this is actually the best use-case for DRF-ME and somehow it is not fully supported yet.

Ok, this is a high-priority improvement. I'm a bit busy, finishing customization of nested fields. I'll need to create a special case in DocumentSerializer.build_field() for DynamicEmbeddedDocuments for release 3.3.3.

If you could help me with this, I'd be very grateful to you - I really have more work than time.

Hello guys @BurkovBA @DaytonG I'm trying to solve a similar problem except in my case the above-mentioned configuration field is EmbeddedDocumentListField and I'm also making PolicyConfig dynamic. Basically my MSV looks as follows:

serializers.py

class ConfigurationSerializer(serializers.EmbeddedDocumentSerializer, serializers.DynamicDocumentSerializer):
    class Meta:
        model = Configuration
        fields = '__all__'


class PolicyConfigurationSerializer(serializers.DynamicDocumentSerializer):
    configuration = ConfigurationSerializer(many=True)

    class Meta:
        model = PolicyConfig
        fields = '__all__'

models.py

class Configuration(mongoengine.DynamicEmbeddedDocument):
    storage = mongoengine.IntField(required=True)
    notify = mongoengine.BooleanField(required=True)


class PolicyConfig(mongoengine.DynamicDocument):
    account_id = mongoengine.StringField(required=True)
    policy_id = mongoengine.StringField(required=True)
    configuration = mongoengine.EmbeddedDocumentListField(Configuration)

views.py

class ConfigModel(viewsets.ModelViewSet):
    lookup_field = 'id'
    serializer_class = PolicyConfigurationSerializer

And if I try to post a json obj that looks like so:

{
	"account_id": "11231354",
	"policy_id": "AAAABBBQAA",
	"configuration": [{"storage": 151, "notify": false}, {"storage": 10, "notify": true}]
}

it errors out with AttributeError at /api/v1/config 'ConfigurationSerializer' object has no attribute 'initial_data'. I'm totally clueless how to make the whole thing work. Your help would be greatly appreciated!

@gitrulesforreal

Mate, I'm sorry, but I still didn't manage to fix this issue. To be honest, this project needs another maintainer, cause I'm totally switching to other languages.

I assume that the source of problems is somewhere in to_internal_value() method, which is different for DynamicDocumentSerializer.