回答:
更新:self._stateプライベートインスタンス変数ではないが、競合を回避するためにそのように名前が付けられた明確化により、チェックself._state.addingはチェックするための望ましい方法です。
self.pk is None:
オブジェクトが持っていない限り、新しいモデルオブジェクト内にTrueを返しUUIDField、そのようprimary_key。
あなたが心配しなければならないかもしれない主なケースは、ID以外のフィールドに一意性の制約があるかどうかです(たとえば、他のフィールドのセカンダリ一意インデックス)。その場合、まだ新しいレコードを持っている可能性がありますが、それを保存することはできません。
is notではなく、使用する必要!=がありNoneます
models.OneToOneField(OtherModel, primary_key=True)。つまり、を介して別のモデルが拡張されています。使用する必要があると思いますself.pk
UUIDFieldaを主キーとして使用する場合、self.pk決してではありませんNone。
モデルをself.pkチェックできるチェックself._stateの代替方法
self._state.adding is True 作成
self._state.adding is False 更新
このページから入手した
self._state.adding動作の詳細についてはよくわかりませんが、呼び出し後にFalse確認すると常に等しいように見えるという警告があります:github.com/django/django/blob/stable/1.10.x/django/db/models/ …super(TheModel, self).save(*args, **kwargs)
_state非公開ではありません。のように_meta、フィールド名との混同を避けるために、アンダースコアが前に付けられます。(リンクされたドキュメントでの使用方法に注意してください。)
is_new = self._state.addingはそれsuper(MyModel, self).save(*args, **kwargs)から、そしてそれからif is_new: my_custom_logic()
super(...).save()。
のチェックでself.pk == Noneは、オブジェクトがデータベースに挿入または更新されるかどうかを判断するには不十分です。
Django O / RMは特に厄介なハックを特徴としており、基本的にはPKの位置に何かがあるかどうかを確認し、ある場合はUPDATEを実行します。
これを行う必要があるのは、オブジェクトの作成時にPKを設定できるためです。主キーのシーケンス列がある場合は一般的ではありませんが、これは他のタイプの主キーフィールドには適用されません。
本当に知りたい場合は、O / RMが行うことを実行して、データベースを調べる必要があります。
もちろん、コードに特定のケースがあり、そのためself.pk == Noneに知っておく必要があるすべてのことを示している可能性が高いですが、それは一般的な解決策ではありません。
UUIDField、aを主キーとして使用する場合に特に当てはまります。キーはDBレベルで入力されないためself.pk、常にTrueです。
「作成された」クワーグを送信するpost_save信号に接続するだけで、trueの場合、オブジェクトが挿入されています。
http://docs.djangoproject.com/en/stable/ref/signals/#post-save
ATOMIC_REQUESTSしているので、デフォルトについて本当にわかりません。
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値があるため、これは便利です
を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メソッドをブロックするため、フォームを使用している場合でも、AJAX呼び出しにDjango RESTフレームワークを使用している場合でも、応答を送信する前に、トリガー通知やモデルの更新などを行うことができます。もちろん、ユーザーを待たせるのではなく、責任を持って使用し、重いタスクをジョブキューにオフロードしてください:)
むしろ使用PKの代わりにID:
if not self.pk:
do_something()
これは上記のすべてのシナリオで機能しますか?
if self.pk is not None and <ModelName>.objects.filter(pk=self.pk).exists():
...
> def save_model(self, request, obj, form, change):
> if form.instance._state.adding:
> form.instance.author = request.user
> super().save_model(request, obj, form, change)
> else:
> obj.updated_by = request.user.username
>
> super().save_model(request, obj, form, change)
UUIDField pk