我有三个代表消息,明文和密文的模型:
class Message(models.Model):
key = models.ForeignKey(Key, on_delete=models.CASCADE, related_name='messages')
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=50, blank=True, default='')
owner = models.ForeignKey(User, related_name='messages')
class Plaintext(models.Model):
message = models.OneToOneField(
Message,
on_delete=models.CASCADE,
primary_key=True
)
text = models.TextField(blank=True, default='')
class Ciphertext(models.Model):
message = models.OneToOneField(
Message,
on_delete=models.CASCADE,
primary_key=True
)
text = models.TextField(blank=True, default='')
我希望每当创建Plaintext
时都会自动创建Ciphertext
和Message
实例。实现这一目标的最佳方法是什么?
答案 0 :(得分:2)
通过使用post_save信号,您实际上拥有了所需的一切:
from .models import Plaintext, Ciphertext
def create_plain_and_cipher_text(sender, instance, created, **kwargs):
if created:
Plaintext.objects.create(message=instance)
Ciphertext.objects.create(message=instance)
您根本不需要或必须覆盖.save()
上的Message
方法。
幸运的是,post_save
告诉我们新实例是否为created
,只允许您在创建新对象时创建相关模型实例,而不是每次Message
创建相关模型实例。 1}}对象被保存。
答案 1 :(得分:0)
通过动态获取模型构造函数,您不必担心加载顺序。您可以覆盖保存方法或使用post save signal来触发创建操作。
from django.apps import apps
class Message(models.Model):
...
def save(self,*args,**kwargs):
PLAIN_TEXT_MODEL = apps.get_model(app_label='your_app_name_here', model_name='Plaintext')
CIPHER_TEXT_MODEL = apps.get_model(app_label='your_app_name_here', model_name='Ciphertext')
new_pt_model = PLAIN_TEXT_MODEL.objects.create(some_field=self.some_field_in_message_model,some_other_field = 1)
CIPHER_TEXT_MODEL.objects.create(some_field="Something")
super(Message,self).save(*args,**kwargs) # call default save method
使用信号 -
from django.db.models import signals
class Message(models.Model):
...
def your_callable_function(sender, instance, **kwargs):
# do something, create other model instances, etc
signals.post_save.connect(your_callable_function, sender=Message)