新しいレコードを保存するときに(既存のレコードを更新しないで)Django=モデルオブジェクトのsave()メソッドで特別なアクションをトリガーします。)
(self.id!= None)のチェックは、自己レコードが新規で更新されていないことを保証するために必要かつ十分ですか?これが見落とす可能性のある特別なケースはありますか?
self.pk is None:
オブジェクトがprimary_key
としてUUIDField
を持たない限り、新しいModelオブジェクト内でTrueを返します。
心配しなければならない可能性のあるケースは、id以外のフィールドに一意性の制約があるかどうかです(たとえば、他のフィールドのセカンダリ一意インデックス)。その場合、新しいレコードを手に入れることはできますが、保存することはできません。
self.pk
をチェックする別の方法モデルのself._state
をチェックできます
self._state.adding is True
作成
self._state.adding is False
更新
これから得た ページ
self.id
は、id
がモデルの主キーであると想定しています。より一般的な方法は、 pkショートカット を使用することです。
is_new = self.pk is None
self.pk == None
のチェックはnotで、オブジェクトがデータベースに挿入または更新されるかどうかを判断するのに十分です。
Django O/RMは、PK位置に何かがあるかどうかを確認し、そうであればUPDATEを行い、そうでない場合はINSERTを実行する(これはINSERTに対して最適化されます) PKがNoneの場合)。
これを行う必要があるのは、オブジェクトの作成時にPKを設定できるためです。主キーのシーケンス列がある場合は一般的ではありませんが、これは他のタイプの主キーフィールドには当てはまりません。
本当に知りたい場合は、O/RMが行うことを実行し、データベースを調べる必要があります。
もちろん、コードに特定のケースがあり、そのためにself.pk == None
があなたが知る必要があるすべてをあなたに伝える可能性が高いですが、それはnot一般的なソリューション。
「作成済み」のkwargsを送信するpost_save信号に接続するだけで済みます。trueの場合、オブジェクトが挿入されています。
http://docs.djangoproject.com/en/stable/ref/signals/#post-save
self.id
そしてその force_insert
国旗。
if not self.pk or kwargs.get('force_insert', False):
self.created = True
# call save method.
super(self.__class__, self).save(*args, **kwargs)
#Do all your post save actions in the if block.
if getattr(self, 'created', False):
# So something
# Do something else
これは、新しく作成されたオブジェクト(self)にpk
値があるため便利です。
私はこの会話に非常に遅れていますが、デフォルト値が関連付けられているときにself.pkが読み込まれるという問題に遭遇しました。
これを回避する方法は、モデルにdate_createdフィールドを追加することです
date_created = models.DateTimeField(auto_now_add=True)
ここから行くことができます
created = self.date_created is None
むしろidの代わりにpkを使用してください:
if not self.pk:
do_something()
UUIDField
を主キーとしても機能するソリューションの場合(他の人が指摘しているように、None
をオーバーライドするだけではsave
ではありません)、 Djangoの post_save シグナルに接続します。これをmodels.pyに追加します:
from Django.db.models.signals import post_save
from Django.dispatch import receiver
@receiver(post_save, sender=MyModel)
def mymodel_saved(sender, instance, created, **kwargs):
if created:
# do extra work on your instance, e.g.
# instance.generate_avatar()
# instance.send_email_notification()
pass
このコールバックはsave
メソッドをブロックするため、フォームを使用している場合でもDjango REST AJAX呼び出しのフレームワーク。もちろん、責任を持って使用し、ユーザーを待たせずに重いタスクをジョブキューにオフロードします:)
これが一般的な方法です。
iDは、dbに最初に保存されている間に与えられます
これは上記のすべてのシナリオで機能しますか?
if self.pk is not None and <ModelName>.objects.filter(pk=self.pk).exists():
...