我正在尝试为我的 Django 项目中的模型类创建自定义管理器。
模型类Story
和Plot
具有一对一关系。我希望Plot
在创建新的 Story 实例时自动创建一个新实例。目前我通过视图函数执行此操作,但在没有视图函数的情况下测试 Story 对象创建时会失败。
我知道有几种方法可以实现这一点,但我决定使用自定义管理器通过覆盖objects.create
方法来添加此创建后逻辑。相关代码如下:
class Story(models.Model):
... other fields
objects = models.Manager()
class Plot(models.Model):
... other fields
story = models.OneToOneField(Story, on_delete=models.CASCADE, null=True, default=None, related_name='plot')
class StoryManager(models.Manager):
def create(self, **kwargs):
story = super().create(**kwargs)
plot = Plot.objects.create(
... other kwargs,
story_id=story.id
)
return story
# Assign the story manager to the Story model
Story.objects = StoryManager()
现在,我在运行使用该方法的测试时得到了以下回溯Story.objects.create
:
File "C:\Users\jacob\documents\programming\story-builder\storybuilder\app\models.py", line 221, in create
story = super().create(**kwargs)
File "C:\Users\jacob\documents\programming\story-builder\.venv\Lib\site-packages\django\db\models\manager.py", line 87, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "C:\Users\jacob\documents\programming\story-builder\.venv\Lib\site-packages\django\db\models\query.py", line 669, in create
self.model._meta._reverse_one_to_one_field_names
^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '_meta'
我对 Django ORM 的概念及其内部工作原理还不熟悉,所以也许这甚至不是在创建其他对象时自动创建对象的推荐方法。在我迄今为止的研究中,我看到了覆盖第一个模型的保存方法的建议,这是不切实际的,因为保存方法是在关联的模型类之前定义的。
我也考虑过发出post_save
信号,但我的印象是它们有很多潜在的副作用,很难调试,而且大多数时候最好使用自定义管理器创建之类的选项。