Django OneToOneField теряет связь, возвращая None после save()
Я немного запутался в поведении Django, и я не смог найти это ни в соответствующих вопросах, ни в официальной документации.
Например, в коде ниже:
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=255)
class Post(models.Model):
title = models.CharField(max_length=255)
category = models.OneToOneField(Category)
post = Post(title='My Title')
post.category = Category(name='My Category')
post.category.save()
# Here: post.category => Category(pk=1, name="My Category") 🎉
post.save()
# Here: post.category => None 😭
Я создаю объект Post. Затем я создаю на нем категорию, которую сохраняю перед сохранением поста. Но когда я вызываю метод post.save()
, post.category
очищается и устанавливается в None. Почему так происходит?
Я исправил это, сделав следующее, что вводит дополнительную переменную:
post = Post(title='My Title')
category = Category(name='My Category')
category.save()
post.category = category
# Here: post.category => Category(pk=1, name="My Category") 🎉
post.save()
# Here: post.category => Category(pk=1, name="My Category") 🎉
Почему введение дополнительной переменной изменяет поведение метода save()
?
Поскольку django использует lazy для своего кверисета, транзакция базы данных не выполняется, пока не будет вызвана save():
post = Post(title='My Title')
# cool you created a post instance of Post model(not database record)
post.category = Category(name='My Category')
# you set the instance attribute value to an instance of Category model
post.category.save()
# calling save() execute database transaction -> it create category object in DB -> your post instance with its attribute never get saved
post.save()
# now you only be saving Post(title='My Title')
Я не думаю, что это лучший ответ, но он объяснил поток
TLDR: ваш первый save() выполняется только для экземпляра Category, а не для экземпляра Post