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> 之间的区别。哪一个是正确的方式?
答案 0 :(得分:1)
您的第一个示例可以重写以减少数据库使用量(因为它目前已经显示,它会INSERT
payment=NULL
,后跟UPDATE
。这应该更好:
order = Order.objects.first()
payment = Payment.objects.create(order=order)
现在,问题。两种方法几乎完全相同。但是,如果您使用的是django> = 1.9,则会有所不同。 .add
现在默认执行批量插入,而不是在每个实例上调用save
。这意味着如果您有post_save
或post_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方法添加关联,因为与保存相关的信号不会触发。