Если под 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 документа
- Когда использовать select_related
- Как вернуть ReferenceField в JSON
- Если поле возвращает только id
- Как проверить в MongoDB
- Частые ошибки
- Путают MongoDB и MongoEngine
- Сохраняют строку вместо документа
- Не проверяют None
- Слишком много связанных загрузок
- Что почитать дальше по MongoDB
Если у вас есть 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
}
}
Когда использовать select_related
Если вы выводите список постов и у каждого нужен автор, отдельная загрузка автора для каждого поста может быть лишней. В 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. Для соседних задач пригодятся эти разборы:
- Discord bot на Python и MongoDB: как задать проверку
- Failed to start MongoDB database server: что проверить
- MongoDB Atlas: облачная база для первого проекта
- MongoDB Compass: подключение и первая коллекция без командной строки



