Лучшая практика создания записи модели в сигнале `post_save` при сохранении целостности данных в Django
Я работаю над приложением Django, где мне нужно автоматически создавать запись Setting
со значениями по умолчанию каждый раз, когда создается новая запись User
. Моя текущая реализация использует сигнал post_save
модели User
для обработки этой логики.
from django.db.models.signals import post_save
from django.db import transaction
from django.contrib.auth.models import User
from myapp.models import Setting
@receiver(post_save, sender=User)
def create_default_setting(sender, instance, created, **kwargs):
if created:
transaction.on_commit(lambda: Setting.objects.create(user=instance))
Я использовал transaction.on_commit, чтобы убедиться, что создание Setting
записи происходит только после того, как транзакция создания User
зафиксирована , чтобы избежать проблем, когда экземпляр User
может еще не существовать в базе данных. Однако это отделяет создание Setting
от транзакции создания User
. Если по какой-либо причине создание Setting
не удастся (например, ошибки валидации, проблемы с базой данных), то в итоге я получу запись User
без соответствующей Setting
, что нарушит целостность данных.
С другой стороны, если я не использую transaction.on_commit
и создаю Setting
непосредственно в сигнале post_save
, есть риск попытаться создать запись Setting
до того, как экземпляр User
будет полностью сохранен в базе данных, или создать Setting
даже тогда, когда создание User
завершится неудачей из-за незафиксированной или откаченной транзакции.
Таким образом, у меня остается два несовершенных решения:
- Используя
transaction.on_commit
: Обеспечивает фиксациюUser
до созданияSetting
, но рискует получить неполные данные в случае неудачи при созданииSetting
. - Без
transaction.on_commit
: Риск попытки создатьSetting
до того, какUser
будет полностью сохранен, или создания ненужныхSetting
записей в неудачных транзакциях.
Мои вопросы:
Какова наилучшая практика работы с такими сценариями в Django, когда запись одной модели зависит от успешного создания записи другой модели?
Есть ли способ обеспечить, чтобы записи
User
иSetting
создавались в рамках одной транзакции, чтобы гарантировать целостность данных, избегая условий гонки или преждевременных запросов?
Любые рекомендации или предложения будут высоко оценены. Спасибо!
Вы можете создать Setting
без использования transaction.on_commit
. Это гарантирует, что в случае сбоя основной транзакции вся транзакция, включая все записи, созданные в сигналах и в методе save
вашей модели, будет откачена.