Djangoのドキュメントはのみ上書きする例リストsave()
とをdelete()
。ただし、モデルが作成されたときにのみ、モデルに追加の処理を定義したいと思います。Railsに精通している人にとっては、:before_create
フィルターを作成するのと同じです。これは可能ですか?
Djangoのドキュメントはのみ上書きする例リストsave()
とをdelete()
。ただし、モデルが作成されたときにのみ、モデルに追加の処理を定義したいと思います。Railsに精通している人にとっては、:before_create
フィルターを作成するのと同じです。これは可能ですか?
回答:
オーバーライド__init__()
すると、オブジェクトのPython表現がインスタンス化されるたびにコードが実行されます。レールはわかりませんが: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)
create
か?これは興味深い解決策ですが、オブジェクトがObject(**kwargs).save()
それを使用して、またはその他のバリエーションを使用して作成されている場合は機能しません。
super(MyModel, self).save(*args, **kwargs)
ですか?
self.pk
オブジェクトが新しく作成されているのか、単に更新されているのかを確認するのに最適なオプションではないかもしれません。作成時にオブジェクトID(のようなカスタマイズされた非データベース生成値KSUID
)を指定すると、この句が実行さself._state.adding
れない場合があります...初めて保存するのか、単に更新するだけなのかを確認する値があります。そのような場合に役立ちます。
これは古く、受け入れられた答えが機能し(Zachのもの)、より慣用的なもの(Michael Bylstraのもの)もありますが、それでもほとんどの人が見るGoogleでの最初の結果であるため、よりベストプラクティスのモダンなdjangoが必要だと思いますここでスタイルの答え:
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つのメソッドである必要があります。)
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 /
私の意見では、このタスクにシグナルを使用すると、より堅牢で読みやすくなりますが、時間がかかります。
instance.save()
。したがって、この場合、データベースへのINSERTクエリとUPDATEクエリが1つずつあるため、パフォーマンスが低下します。
文字通り質問に答えるため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