ken
ken

Reputation: 2682

Flask-restful How to `marshal_with()` data in reference_field of mongoengine?

I use Flask-restful and MongoEngine,I want to show the data in ReferenceField of my model in the JSON.

I have this 2 model, RoomModel have a ReferenceField to UserModel:

class RoomModel(Document):
    meta = {'allow_inheritance': True}

    room_name = StringField()
    created_by = ReferenceField(UserModel)

class UserModel(Document):

    username = StringField()
    email = StringField()

I want to marshal_with() all the data get from the mongoengine query to the response,so I done this:

     room_model_fields = {
        'room_name': fields.String,
        'created_by': fields.String(attribute=UserModel._id)
    }

    room_model_fields_format = {
        'rooms': fields.List(fields.Nested(room_model_fields))
    }


    @staticmethod
    @marshal_with(room_model_fields_format)
    def get():
        room = RoomModel.objects().all() 
        return {'rooms': room},200

I get this response:

{
 rooms": [
    {
      "room_name": "mobile_legend",
      "created_by": "UserModel object" <<--Now: This only return a string with "UserModel object"
      "created_by": "SOME_ID_STRING"  <<-- THIS IS WHAT I WANT
    }
  ]
}

I see my database,it have a field with created_by: SOME_ID_STRING_HERE,I want the SOME_ID_STRING show in the response instead of "UserModel object" string.

How can I solve this problem?

Upvotes: 0

Views: 1574

Answers (2)

notfound404
notfound404

Reputation: 76

In my case, accepted answer didn't work. I solved with my custom class that inherit fields.raw class doc and return reference id of the class. Hope it will be helpful for related issues

snippet

class CustomObjectId(fields.Raw):
    def format(self, value):
        return value.id
    
response_model = create_model.clone(
        'response model',
        {
            'id': fields.String(),
            'author': CustomObjectId(),
        })

Upvotes: 1

bagerard
bagerard

Reputation: 6374

You need to use attribute='created_by.id'. See the example below:

from mongoengine import StringField
from flask_restful import fields, marshal_with

class Car(Document):
    brand = StringField()

class User(Document):
    car = ReferenceField(Car)
    name = StringField()

car = Car(brand='VW').save()
user = User(car=car, name='John Doe').save()

@marshal_with({'name': fields.String, 'id': fields.String, 'car_id': fields.String(attribute='car.id')})
def get():
    return user

print(dict(get()))    # {'car_id': u'5e124e83aa7a179157418ab2', 'name': u'John Doe', 'id': u'5e124e83aa7a179157418ab3'}

Upvotes: 0

Related Questions