2016-11-14 3 views
1

私が何をしたいのかmodels.pyDjango:オブジェクトにforeignkeyフィールドを割り当てますか?

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にそれを追加することです。

paymentフィールドなしですでにOrderが作成されているとします。

< 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との違いは何か知りたいです>。どちらが正しいのですか?

答えて

1

DBの使用量を減らすために、最初の例を書き直すことができます(現時点ではpayment=NULLINSERT、それに続いてUPDATEとなります)。これはより良いはずです:

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

今、質問に。どちらのアプローチもほぼ同じです。ただし、django> = 1.9を使用している場合は違いがあります。 .addは、各インスタンスでsaveを呼び出す代わりに、デフォルトで一括挿入を実行します。これは、あなたがpost_saveたりPaymentモデルに接続post_createのような任意の信号を持っている場合は、明示的bulk=Falseを指定しない限り、あなたがそれらを実行していないことを意味します:

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

私はあなたがあなたの関係、あなたの周りに間違った方法を持っているかもしれないと思います最初のシナリオ。行3と4があるべきである。

payment.order = order 
payment.save() 

1インスタンスでFKを設定します。

お支払いの保存方法が呼び出され、1つのお支払いを1つの注文と関連付けることになります。 Payment.saveが呼び出され、関連する信号を保存します。

2:RelatedManager.add methodを使用します。

この方法を使用すると、実際に複数の関連付けを同時に追加できます。だから、例えば、あなたが使用して1回の注文で複数の支払いを関連付けることができます:

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

重要なのは、デフォルトではDjango 1.9以降、支払いをせずに作成され、その保存()を使用すると、関連信号を保存取得することはできませんので、メソッドは、呼び出されています発射。それは、Djangoアプリケーションでsignalsを使用することは非常に一般的です

:信号の発射を保存することの重要性に

。モデルロジックを乱雑にすることなく、アプリケーションに機能を追加する強力な方法を提供します。アプリケーションで使用している場合は、関連する保存関連のシグナルが発生しないため、関連マネージャーを使用して関連付けを追加することをお勧めします。

関連する問題