Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django-在创建一个实例时触发其他实例的创建_Python_Django - Fatal编程技术网

Python Django-在创建一个实例时触发其他实例的创建

Python Django-在创建一个实例时触发其他实例的创建,python,django,Python,Django,我有三种表示消息、明文和密文的模型: 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=

我有三种表示消息、明文和密文的模型:

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='')

我希望在创建
消息时自动创建
明文
密文
实例。实现这一点的最佳方法是什么?

通过动态获取模型构造函数,您不必担心加载顺序。您可以重写save方法或使用来触发创建操作

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)

通过动态获取模型构造函数,您不必担心加载顺序。您可以重写save方法或使用来触发创建操作

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)

实际上,只要使用一个信号,您就拥有了所需的一切:

您根本不需要或不必重写
消息
上的
.save()
方法


幸运的是,
post\u save
告诉我们是否创建了一个新实例
,允许您仅在创建一个新对象时创建相关的模型实例,而不是每次保存一个
消息
对象时。

您实际上只需使用一个信号即可获得所需的一切:

您根本不需要或不必重写
消息
上的
.save()
方法


幸运的是,
post\u save
告诉我们是否创建了一个新实例
,允许您仅在创建新对象时创建相关的模型实例,而不是每次保存
消息
对象时都创建。

我已经尝试在
消息
上覆盖
save
。我想知道是否有一种标准的方法可以做到这一点。您会想看看:我已经尝试在
消息
上覆盖
保存
。我想知道是否有一个标准的方法来做到这一点。你会想看看:模型是注册在。如果直接导入模型,则不必担心加载顺序,因为将模型加载到注册表是导入模型的副作用。没有理由使用apps.get_model()
,除非您需要动态获取不同的模型类。如果这些模型在同一个
models.py
中,并且按照OP列出的顺序定义,则会引发
NameError
。对,这是一个文件。仍然不需要使用
apps.get\u model()
,在调用
.save()
方法之前,将运行所有类定义。测试在方法中使用模型实际上不会导致
名称错误
,即使方法本身是在它引用的类之前定义的,这一点很简单。很好的调用,在早期的Django(1.4?)中构建了一些类似的方法。我不得不这样做(使用早期版本的
get_model
)。刚刚更新,没有电话,没有问题。模型已在中注册。如果直接导入模型,则不必担心加载顺序,因为将模型加载到注册表是导入模型的副作用。没有理由使用apps.get_model()
,除非您需要动态获取不同的模型类。如果这些模型在同一个
models.py
中,并且按照OP列出的顺序定义,则会引发
NameError
。对,这是一个文件。仍然不需要使用
apps.get\u model()
,在调用
.save()
方法之前,将运行所有类定义。测试在方法中使用模型实际上不会导致
名称错误
,即使方法本身是在它引用的类之前定义的,这一点很简单。很好的调用,在早期的Django(1.4?)中构建了一些类似的方法。我不得不这样做(使用早期版本的
get_model
)。只是在没有呼叫的情况下进行了更新,没有其他问题。我只想澄清一些文档中没有立即澄清的问题:如果我使用
@receiver
装饰器,我不必呼叫
信号。连接
,对吗?正确。您只需确保您的信号代码已注册。我只想澄清文档中未立即明确的一点:如果我使用
@receiver
装饰器,我不必调用
信号。连接
,对吗?正确。你只需确保你的信号代码已注册。