Как получить ReferenceField из MongoDB через Flask-MongoEngine

Если под flasmongengine имеется в виду Flask-MongoEngine или MongoEngine, то ReferenceField получают как обычное поле документа. В базе MongoDB ссылка хранится как id другого документа, а MongoEngine при обращении к полю может загрузить связанный объект

Пример моделей:

from flask_mongoengine import MongoEngine

db = MongoEngine()

class User(db.Document):
    name = db.StringField(required=True)

class Post(db.Document):
    title = db.StringField(required=True)
    author = db.ReferenceField(User, required=True)

Создание:

user = User(name="Dinar").save()
post = Post(title="Первый пост", author=user).save()

Получение:

post = Post.objects.first()
print(post.author.name)

Здесь post.author — связанный User, а не просто строка с id

Если у вас есть id документа

Можно найти пост и получить автора:

post = Post.objects(id=post_id).first()

if post:
    author = post.author
    print(author.name)

Если нужен сам id автора:

print(post.author.id)

Для API часто возвращают и id, и короткие данные автора:

{
    "id": str(post.id),
    "title": post.title,
    "author": {
        "id": str(post.author.id),
        "name": post.author.name
    }
}

Если вы выводите список постов и у каждого нужен автор, отдельная загрузка автора для каждого поста может быть лишней. В MongoEngine для таких случаев используют select_related:

posts = Post.objects.select_related()

for post in posts:
    print(post.title, post.author.name)

Это помогает уменьшить количество дополнительных обращений к базе

Как вернуть ReferenceField в JSON

Для ответа API не отдавайте объект MongoEngine напрямую. Соберите словарь вручную:

def post_to_dict(post):
    return {
        "id": str(post.id),
        "title": post.title,
        "author": {
            "id": str(post.author.id),
            "name": post.author.name,
        }
    }

Так вы контролируете, какие поля связанного документа попадут наружу. Это особенно важно, если в User есть email, настройки или другие поля, которые не нужно показывать в публичном ответе

Если поле возвращает только id

Проверьте три вещи. Во-первых, в модели должен быть именно ReferenceField(User). Во-вторых, при сохранении лучше передавать объект user, а не случайную строку. В-третьих, связанный пользователь должен существовать в коллекции

Неправильно:

Post(title="Пост", author="665f1c1a7b8c2e0012a4d111").save()

Лучше:

user = User.objects(id=user_id).first()
Post(title="Пост", author=user).save()

Если пользователя нет, сначала обработайте это:

if not user:
    raise ValueError("Пользователь не найден")

Как проверить в MongoDB

В самой MongoDB вы увидите ссылку как id:

db.post.findOne()

Это нормально. MongoDB не делает автоматический join как SQL. Загрузку связанного документа выполняет MongoEngine на уровне Python-кода

Если хотите убедиться, что ссылка живая, откройте id из поля автора и найдите документ в коллекции пользователей. Если пользователя нет, ссылка сохранена, но получить post.author.name корректно уже не получится

Частые ошибки

Путают MongoDB и MongoEngine

В MongoDB поле хранит ссылку. Удобное обращение post.author.name дает MongoEngine

Сохраняют строку вместо документа

Передавайте объект или корректный id, который MongoEngine сможет преобразовать

Не проверяют None

Если Post.objects(...).first() вернул None, обращение к post.author упадет

Слишком много связанных загрузок

Для списков используйте select_related или заранее подумайте, какие поля автора реально нужны

Что почитать дальше по MongoDB

Если нужен общий маршрут по теме, откройте рубрику MongoDB. Для соседних задач пригодятся эти разборы:

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x