Addtional Features

FollowReferenceField

This script also provides a field that supports serialization of the reference with follow_reference=True. Unlike ReferenceField, this field supports deserialization and automatic-save.

To use this field, you can just simply declare the field as usual. For example, like this:

import mongoengine as db
import mongoengine_goodjson as gj


class User(gj.Document):
  """User info."""
  name = db.StringField()
  email = db.EmailField()

class DetailedProfile(gj.Document):
  """Detail profile of the user."""
  # FollowReferenceField without auto-save
  user = gj.FollowReferenceField(User)
  yob = db.DateTimeField()
  # FollowReferenceField with auto-save
  partner = gj.FollowReferenceField(User, autosave=True)

Exclude fields from JSON serialization/deserialization

Sometimes you might want to exclude fields from JSON serialization, but to do so, you might need to decode JSON-serialized string, pop the key, then, serialize the dict object again. Since 0.11, metadata exclude_to_json, exclude_from_json, and code:exclude_json are available and they exclude field on the following specific actions:

  • Setting Truthy value to exclude_to_json, the corresponding field is omitted from JSON encoding. Note that this excludes fields JSON encoding only.
  • Setting Truthy value to exclude_from_json, the corresponding field is omitted from JSON decoding. Note that this excludes fields JSON decoding only.
  • Setting Truhy value to exclude_json, the corresponding field is omitted from JSON encoding and decoding.

Example

To use the exclusion, you can just put exclude metadata like this:

import mongoengine_goodjson as gj
import mongoengine as db


class ExclusionModel(gj.Document):
    """Example Model."""
    to_json_exclude = db.StringField(exclude_to_json=True)
    from_json_exclude = db.IntField(exclude_from_json=True)
    json_exclude = db.StringField(exclude_json=True)
    required = db.StringField(required=True)


def get_json_obj(*q, **query):
    model = Exclude.objects(*q, **query).get()
    # Just simply call to_json :)
    return model.to_json()


def get_json_list(*q, **query):
    # You can also get JSON serialized text from QuerySet.
    return Exclude.objects(*q, **query).to_json()


# Decoding is also simple.
def get_obj_from_json(json_text):
  return Exclude.from_json(json_text)


def get_list_from_json(json_text):
  return Exclude.objects.from_json(json_text)

Reference Limit

Since version 1.0.0, the method to limit recursive depth is implemented.

By default, to_json serializes the document until the cursor reaches 3rd level. To change the maximum depth level, change max_depth kwargs.

As of 1.1.0, callable function can be set to max_depth, and to_json calls max_depth with the document that the field holds, and current depth level. If the function that is associated with max_depth returns truthy values, the serialization will be stop.

Note that when you use callable max_depth of FollowReferenceField, the border of the document i.e. the document that max_depth returned truthy value, will NOT be serialized while to_json() does. It just be “id” of the model.

Code Example

Here is the code example of Limit Recursion:

import mongoengine as db
import mongoengine_goodjson as gj


class User(gj.Document):
  """User info."""
  name = db.StringField()
  email = db.EmailField()
  # i.e. You can access everyone in the world by Six Degrees of Separation
  friends = db.ListField(gj.FollowReferenceField("self", max_depth=6))

  # If the name of the user is Alice, Mary, or Bob, it will refer more depth.
  not_friend = gj.FollowReferenceField(
    "self", max_depth=lambda doc, cur_depth: doc.name not in [
      "Alice", "Mary", "Bob"
    ]
  )

class DetailedProfile(gj.Document):
  """Detail profile of the user."""
  user = gj.FollowReferenceField(User)
  yob = db.DateTimeField()

To disable the limit, put negative number to max_depth, however you should make sure that the model has neither circuit nor self-reference.