Search code examples
djangomongodbdjango-rest-frameworkdjango-nonrel

Why django-rest-framework (using django-nonrel with mongodb) sets to null child objects PKs when updating an instance


It happens with any object instance that contains embbeded models. When I attempt to update the father instance, it sets to null its childs PKs.

This is an extract of a json object already updated:

{
"pk": "558d023d153bd41930b3fcf0",
"checkgroup_id": "checkgroupid 5",
"name": "checkgroup five",
"description": "this an example description",
"control_config": {
    "control_config_1": {
        "pk": null,
        "params": {
            "param2": {
                "pk": null,
                "value": "value2",
                "mandatory": false,
                "default": "default"
            },
            "param1": {
                "pk": null,
                "value": "value1",
                "mandatory": false,
                "default": "default"
            }
        },
        "exceptions": {
            "exception1": {
                "pk": null,
                "description": "description example",
                "params": [
                    {
                        "pk": null,
                        "value": "value1",
                        "mandatory": false,
                        "default": "default"
                    },
                    {
                        "pk": null,
                        "value": "value2",
                        "mandatory": false,
                        "default": "default"
                    }
                ]
            }
        }
    }
},

and this is the Model:

class CheckGroup(models.Model):
"""It defines a set of controls to be applied. """
    checkgroup_id = models.TextField(max_length=250)
    name = models.TextField(max_length=250)
    description = models.TextField(max_length=250)
    control_config = DictField(EmbeddedModelField(ControlConfig))
    controls = DictField(EmbeddedModelField(Control))

with its serializer defined as:

class CheckGroupSerializer(serializers.ModelSerializer):
""" Transforms CheckGroup into json
"""
control_config =  serializers.DictField(child=ControlConfigSerializer())
controls = serializers.DictField(child=ControlSerializer())
pk = serializers.CharField()

class Meta:
    """ It lets to choose the model that will be serialize and its         fields
    """
    model = CheckGroup
    fields = ('pk', 'checkgroup_id', 'name', 'description', 'control_config', 'controls')

Solution

  • Well, I found out the reason on django-rest-framework docs. The problem is that the framework does not deal with that, and should be implemented by us.

    The doc says:

    Because the behavior of nested creates and updates can be ambiguous, and may require complex dependencies between related models, REST framework 3 requires you to always write these methods explicitly. The default ModelSerializer .create() and .update() methods do not include support for writable nested representations.