pythonmongodbflaskmongoengine

How do relationships work on the mongoengine?


I'm new in mongoengine and I'm trying to relate two documments.

class Actor(Document):
    name = StringField(required=True, unique=True)
    movies = ListField()

class Movie(Document):
    title = StringField(required=True, unique=True)
    release_date = DateField()
    director = StringField()
    cast = ListField(ReferenceField(Actor))

I'd like to list the actors and have the movies appear. Or list the movies and the actors would appear related.

In my mind, I think of something like this:

class Actor(Resource):
    def get_actors(self) -> Response:
        for actor in Actor.objects.all():
            movies = Movie.objects(actors=actor)
            [...]
        return Response(planets, mimetype='application/json', status=200)

Is this a valid path, or is my head in Postgres and Mongo different? Any ideas?


Solution

  • In mongoengine, if you use ReferenceField, this will auto queryset to Actor. So you only need create a function to return a dict value.

    class Actor(Document):
        name = StringField(required=True, unique=True)
        movies = ListField()
    
        def as_dict(self):
            return {
                "id": str(self.pk),
                "name": self.name,
                "movies": self.movies
            }
    
    class Movie(Document):
        title = StringField(required=True, unique=True)
        release_date = DateField()
        director = StringField()
        cast = ListField(ReferenceField(Actor))
        
        def as_dict(self):
            return {
                "id": str(self.pk),
                "title": self.title,
                "release_date": self.release_date.isoformat(),
                "director": self.director,
                "cast": [i_cast.as_dict() for i_cast in self.cast]
            }
    

    In API, you only call ac_dict after query to return data

    def get_actors(self) -> Response:
        actors = Actor.objects.all()
        return Response([actor.as_dict() for actor in actors], mimetype='application/json', status=200)