0

I have two mongoengine Document models as:

from mongoengine import *

class Doc1(Document):
  doc1_field1 = StringField(max_length=100)
  doc1_field2 = StringField(max_length=100)

class Doc2(Document):
  doc2_field1 = ReferenceField(Doc1)
  doc2_field2 = StringField(max_length=100)

in serializers.py:

from rest_framework_mongoengine import serializers
from .models import Doc1, Doc2

class Doc1Serializer(serializers.DocumentSerializer):

   class Meta:          
      model = Doc1
      fields = '__all__'

class Doc2Serializer(serializers.DocumentSerializer):

   doc2_field1 = Doc1Serializer()

   class Meta:
      model = Doc2
      fields = ('doc2_field1', 'doc2_field2')

views.py

from rest_framework_mongoengine import viewsets
from .models import Doc2
from .serializers import Doc2Serializer

class Doc2ViewSet(viewsets.ModelViewSet):

   lookup_field = 'pk'

   serializer_class = Doc2Serializer

   def get_queryset(self):
     return Doc2.objects.all()

What I'm trying to achieve is when I make a GET request the doc2_field1 should come dereferenced based on the Doc1Serializer and this is actually the case right now. The problem is when I try to PUT/PATCH a doc2_field1 with a new ObjectID reference as defined in models.py. That is where I get the following:

"non_field_errors": [ "Invalid data. Expected a dictionary, but got str." ]

So my question is if there is a way to get a field dereferenced in GET but allow for Object references in PUT/PATCH.

EXPECTED:

GET:

{
  "doc2_field1": {
  "doc1_field1": "Text Value 1",
  "doc1_field2": "Text Value 2"
  },
  "doc2_field2": "Text Value"
}

PUT/PATCH:

{
  "doc2_field1": "5ae1a104e35e8620801798f3"
  "doc2_field2": "Text Value"
}
unicorn
  • 139
  • 1
  • 9
  • Can you add examples what data do you need to PUT and what you expect from GET? – neverwalkaloner Apr 26 '18 at 11:47
  • **GET**: `{ "doc2_field1": { "doc1_field1": "Text Value 1", "doc1_field2": "Text Value 2" } "doc2_field2": "Text Value" }` **PUT/PATCH**: `{ "doc2_field1": "5ae1a104e35e8620801798f3" "doc2_field2": "Text Value" }` PUT a ReferenceId, GET referenced object data – unicorn Apr 26 '18 at 11:56

1 Answers1

1

You can override Doc2Serializer's to_representation method to show details only for GET requests:

class Doc2Serializer(serializers.DocumentSerializer):

   class Meta:
      model = Doc2
      fields = ('doc2_field1', 'doc2_field2')

   def to_representation(self, instance):
      self.fields['doc2_field1'] = Doc1Serializer()
      return super(Doc2Serializer, self).to_representation(instance)
neverwalkaloner
  • 46,181
  • 7
  • 92
  • 100