在Django中创建一个对象时创建另一个对象

5
在Django中创建一个对象时也能同时创建另一个对象吗?我有如下代码,想要在创建AnotherModel实例之前先创建Model实例(同时创建AnotherModel)。
class Model(models.Model):
    name = models.CharFiled(max_length=50)

class AnotherModel(models.Model):
    model = models.ForeignKey(Model, on_delete=models.CASCADE)
    description = models.TextField()

我尝试使用Django信号 - pre_save。

@receiver(pre_save, sender=AnotherModel)
def save_model(sender, **kwargs):
    # some code

但是我遇到了这样的异常:
ValueError: 无法赋值 "u'Test": "AnotherModel.resource" 必须是一个 "Model" 实例。

看起来你用了错误的方式 # some code,因为你将你的 Modelname 设置为了 AnotherModelmodel(好吧,是 resource)而不是它的主键。但话说回来,信号通常不是一个好主意:https://lincolnloop.com/blog/django-anti-patterns-signals/ 很多 ORM 调用,如 .update(..).bulk_create 等,都可以规避这些问题。 - Willem Van Onsem
@swozny13,你能提供创建AnotherModel实例的代码行吗? - lmiguelvargasf
2个回答

7

在Django中,当我创建另一个对象时,是否可以创建对象?

是的,你可以这样做,有两个选项:

1) 选项1: 重写 save 方法 ( 重写预定义的模型方法 )

from django.db import models

class AnotherModel(models.Model):
    model = models.ForeignKey(Model, on_delete=models.CASCADE)
    description = models.TextField()

    def save(self, *args, **kwargs):
        if self.pk is None:  # create
            self.model = Model.objects.create( name = "some random name" )
        super().save(*args, **kwargs)  # Call the "real" save() method.

2) 选项 2: 使用 pre-save 信号:

from django.db.models.signals import pre_save
from django.dispatch import receiver    

@receiver(pre_save, sender=AnotherModel)
def my_handler(sender, **kwargs):
    if sender.pk is None:  # create
        sender.model = Model.objects.create( name = "some random name" )

重要提示:

在保存当前模型之前,必须先创建相关模型。在示例中,我使用了以下方法:

Model.objects.create( name = "some random name" )

但是您可以像常规方式一样创建模型:

m = Model()
m.name = "random name"
m.save()  # <--- important!

0

是的,当创建另一个对象时,可以创建一个对象。我认为使用信号可能是最好的方法。

from django.db.models.signals import pre_save
from django.dispatch import receiver    

@receiver(pre_save, sender=AnotherModel)
def my_handler(sender, **kwargs):
    if sender.pk is None:
        sender.model = Model.objects.create(name="Name")

你只需要创建一个 AnotherModel 的实例,这样就会触发实现的信号:

>>> o = AnotherModel.objects.create(description='This is a silly description')

您可以检查是否已创建Model的实例并将其分配给o.model

>>> o.model

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接