Django docs は、save()
およびdelete()
をオーバーライドする例のみをリストしています。ただし、モデルの追加処理は、作成されたときにのみ定義したいと思います。 Railsに精通している人にとっては、:before_create
フィルタ。これは可能ですか?
__init__()
をオーバーライドすると、pythonオブジェクトの表現がインスタンス化されるたびにコードが実行されます。Railsがわかりませんが、_:before_created
_フィルターが鳴りますデータベースにオブジェクトが作成されたときに実行されるコードのように、データベースに新しいオブジェクトが作成されたときにコードを実行する場合は、save()
をオーバーライドして、オブジェクトにpk
属性かどうか。コードは次のようになります。
_def save(self, *args, **kwargs):
if not self.pk:
# This code only happens if the objects is
# not in the database yet. Otherwise it would
# have pk
super(MyModel, self).save(*args, **kwargs)
_
post_saveシグナルを作成する方法の例( http://djangosnippets.org/snippets/500/ から)
from Django.db.models.signals import post_save
from Django.dispatch import receiver
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
"""Create a matching profile whenever a user object is created."""
if created:
profile, new = UserProfile.objects.get_or_create(user=instance)
ここでは、シグナルを使用するのが最善か、カスタムの保存方法を使用するのが最善かについての思慮深い議論です https://web.archive.org/web/20120815022107/http://www.martin-geber.com/thought/2007/ 10/29/Django-signals-vs-custom-save-method /
私の意見では、このタスクに信号を使用すると、より堅牢で、読みやすくなりますが、より長くなります。
これは古く、受け入れられている回答があり(Zach's)、より慣用的な回答(Michael Bylstra's)ですが、ほとんどの人が見ているGoogleでの最初の結果であるため、ここで、よりベストプラクティスのモダンジャンゴスタイルの答えが必要です:
from Django.db.models.signals import post_save
class MyModel(models.Model):
# ...
@classmethod
def post_create(cls, sender, instance, created, *args, **kwargs):
if not created:
return
# ...what needs to happen on create
post_save.connect(MyModel.post_create, sender=MyModel)
ポイントはこれです:
@classmethod
の代わりに @staticmethod
ほとんどの場合、コード内で静的クラスメンバーを参照する必要が生じるためです。コアDjangoに実際のpost_create
シグナル。 (メソッドの動作を変更するためにブール引数を渡す必要がある場合は、2つのメソッドである必要があります。)
質問に文字通り答えるには、モデルのマネージャーのcreate
メソッドは、Djangoで新しいオブジェクトを作成する標準的な方法です。オーバーライドするには、次のようにします
_from Django.db import models
class MyModelManager(models.Manager):
def create(self, **obj_data):
# Do some extra stuff here on the submitted data before saving...
# For example...
obj_data['my_field'] = my_computed_value(obj_data['my_other_field'])
# Now call the super method which does the actual creation
return super().create(**obj_data) # Python 3 syntax!!
class MyModel(models.model):
# An example model
my_field = models.CharField(max_length=250)
my_other_field = models.CharField(max_length=250)
objects = MyModelManager()
_
この例では、Managerのメソッドcreate
メソッドをオーバーライドして、インスタンスが実際に作成される前に追加の処理を行います。
注:のようなコード
my_new_instance = MyModel.objects.create(my_field='my_field value')
この変更されたcreate
メソッドを実行しますが、次のようなコード
my_new_unsaved_instance = MyModel(my_field='my_field value')
しない。
__init__()
をオーバーライドすると、モデルがインスタンス化されたときにコードを実行できます。親の__init__()
を呼び出すことを忘れないでください。
カスタムマネージャーでcreateメソッドをオーバーライドするか、モデルクラスにclassmethodを追加できます。 https://docs.djangoproject.com/en/1.11/ref/models/instances/#creating-objects
望ましい答えは正しいですが、オブジェクトが作成されているかどうかを判断するテストは、モデルがUUIDModelから派生している場合は機能しません。 pkフィールドにはすでに値があります。
この場合、これを行うことができます:
already_created = MyModel.objects.filter(pk=self.pk).exists()