Search code examples
pythonjsonflaskmongoenginesimplejson

Flask Jsonify mongoengine query


I have method like this , and want to return as Json , but it writes that Posts object is not Json serializable :S

def show_results_async(text):
   query  =  { '$or':[{'title':{'$regex':text}},{'author':{'$regex':text}} ]}
   posts = Posts.objects(__raw__=(query))
   return jsonify(result = posts)

Solution

  • tl,dr: There is no built-in function that'll convert a MongoEngine document to JSON. So you'll need to write your own.

    In views.py:

    def show_results_async(text):
       query  =  { '$or':[{'title':{'$regex':text}},{'author':{'$regex':text}} ]}
       posts = Posts.objects(__raw__=(query))
       return jsonify(result=posts.to_dict())
    

    In post.py, add:

    def to_dict(self):
       return helper.mongo_to_dict(self)
    

    In helper.py:

    def mongo_to_dict(obj):
        return_data = []
    
        if isinstance(obj, Document):
            return_data.append(("id",str(obj.id)))
    
        for field_name in obj._fields:
    
            if field_name in ("id",):
                continue
    
            data = obj._data[field_name]
    
            if isinstance(obj._fields[field_name], DateTimeField):
                return_data.append((field_name, str(data.isoformat())))
            elif isinstance(obj._fields[field_name], StringField):
                return_data.append((field_name, str(data)))
            elif isinstance(obj._fields[field_name], FloatField):
                return_data.append((field_name, float(data)))
            elif isinstance(obj._fields[field_name], IntField):
                return_data.append((field_name, int(data)))
            elif isinstance(obj._fields[field_name], ListField):
                return_data.append((field_name, data))
            elif isinstance(obj._fields[field_name], EmbeddedDocumentField):
                return_data.append((field_name, mongo_to_dict(data)))
    
        return dict(return_data)
    

    A couple of notes:

    • If your document has additional field types, you need to enhance the helper function above.
    • The helper method above was inspired by Thomas' answer to a question. Additional functionality includes: recursively print out EmbeddedDocuments and include the id of the document.