ちなみに、on_delete
モデルのパラメータは、それがどのように聞こえるかとは逆です。あなたは入れてon_delete
、あなたの記録にを指していることFKエントリが削除された場合にどうするかをDjangoに伝えるためにモデルに外部キー(FK)に。当店はほとんどを使用しているオプションがありPROTECT
、CASCADE
とSET_NULL
。ここに私が考え出した基本的なルールがあります:
- 使用
PROTECT
あなたのFKが本当に変化していることをすべきではないことをルックアップテーブルを指している確かに変更にあなたのテーブルが発生することはありません。誰かがそのルックアップテーブルのエントリを削除しようとした場合PROTECT
、レコードに関連付けられている場合は削除できません。また、ルックアップテーブルのエントリを削除したからといって、 djangoがレコードを削除するのを防ぎます。この最後の部分は重要です。 誰かが私の性別テーブルから性別「女性」を削除した場合、私はその性別を持っていた私の個人テーブルにいたすべての人々を即座に削除したくありません。
CASCADE
FKが「親」レコードを指している場合に使用します。人が多くPersonEthnicityエントリを持つことができるのであれば、(彼/彼女はアメリカインディアン、ブラック、ホワイト可能)、及び人がいることをされて削除された、私は本当にだろう任意の「子」PersonEthnicityエントリを削除することにしたいです。それらは人なしでは無関係です。
- 他のユーザーにルックアップテーブルのエントリの削除を許可したいが、それでも記録を保持したい
SET_NULL
場合に使用します。たとえば、PersonがHighSchoolを持つことができても、その高校が私のルックアップテーブルでなくなっても、私にはそれほど問題ではない場合、私はと言います。これは私の人の記録をそこに残します。私のPersonの高校のFKをnullに設定するだけです。明らかに、そのFK を許可する必要があります。on_delete=SET_NULL
null=True
3つのことすべてを行うモデルの例を次に示します。
class PurchPurchaseAccount(models.Model):
id = models.AutoField(primary_key=True)
purchase = models.ForeignKey(PurchPurchase, null=True, db_column='purchase', blank=True, on_delete=models.CASCADE) # If "parent" rec gone, delete "child" rec!!!
paid_from_acct = models.ForeignKey(PurchPaidFromAcct, null=True, db_column='paid_from_acct', blank=True, on_delete=models.PROTECT) # Disallow lookup deletion & do not delete this rec.
_updated = models.DateTimeField()
_updatedby = models.ForeignKey(Person, null=True, db_column='_updatedby', blank=True, related_name='acctupdated_by', on_delete=models.SET_NULL) # Person records shouldn't be deleted, but if they are, preserve this PurchPurchaseAccount entry, and just set this person to null.
def __unicode__(self):
return str(self.paid_from_acct.display)
class Meta:
db_table = u'purch_purchase_account'
最後の一口として、指定しない場合on_delete
(または指定しない場合)のデフォルトの動作は次のとおりCASCADE
です。これは、誰かが性別テーブルの性別エントリを削除した場合、その性別のすべての個人レコードも削除されたことを意味します!
私は、「疑わしい場合は、設定してくださいon_delete=models.PROTECT
。」次に、アプリケーションをテストします。データを危険にさらすことなく、どのFKに他の値のラベルを付ける必要があるかをすばやく理解できます。
また、それon_delete=CASCADE
が選択している動作である場合、実際にはどのマイグレーションにも追加されないことに注意してください。これはデフォルトなので、置くことon_delete=CASCADE
は何も置かないことと同じです。