Django:用对象分配foreignkey字段?

时间:2016-11-14 08:39:15

标签: django django-models

models.py

class Order(TimeStampedModel): 
    name = models.CharField(max_length=50)

class Payment(TimeStampedModel): 
    order = models.ForeignKey(
        'orders.Order',
        null=True,
        blank=True,
        unique=True,
    )

我想要做的是首先创建Payment并将其添加到Order

我们已经创建了Order而没有payment字段。

< 1>

In [1]: order = Order.objects.first()

In [2]: payment = Payment.objects.create()

In [3]: order.payment = payment

In [4]: order.save()

< 2>

In [7]: order.payment_set.add(payment)

我想知道< 1> < 2> 之间的区别。哪一个是正确的方式?

2 个答案:

答案 0 :(得分:1)

您的第一个示例可以重写以减少数据库使用量(因为它目前已经显示,它会INSERT payment=NULL,后跟UPDATE。这应该更好:

order = Order.objects.first()
payment = Payment.objects.create(order=order)

现在,问题。两种方法几乎完全相同。但是,如果您使用的是django&gt; = 1.9,则会有所不同。 .add现在默认执行批量插入,而不是在每个实例上调用save。这意味着如果您有post_savepost_create的任何信号与Payment模型相关联,除非您明确指定bulk=False,否则您将无法执行这些信号:< / p>

 order.payment_set.add(payment, bulk=False)

答案 1 :(得分:0)

我认为你的关系可能与你的第一种情况有关;第3和第4行应该是:

payment.order = order
payment.save()

<强> 1。在实例上设置FK。

您的付款的保存方法已被调用,您正在将单个付款与单个订单相关联。调用Payment.save,触发保存相关信号。

2:使用RelatedManager.add method

您实际上可以使用此方法一次添加多个关联。例如,您可以使用以下方法将多个付款与一个订单相关联:

order.payment_set.add(payment_1, payment_2, ... payment_N)

重要的是,默认情况下,自Django 1.9以来,付款是在没有调用save()方法的情况下创建的,因此您不会触发与保存相关的信号。

关于保存信号触发的重要性:

在Django应用程序中使用signals是很常见的。它们提供了一种向应用程序添加功能的强大方法,而不会使模型逻辑混乱。如果您的应用程序正在使用它们,请使用RelatedManager.add方法添加关联,因为与保存相关的信号不会触发。