保存具有外键的django模型时,如何一次保存所有内容?

时间:2016-10-28 05:31:58

标签: python django

我目前有以下型号

class Chat(models.Model):
    id   = models.BigAutoField(primary_key=True)

    subject      = models.CharField(max_length=200)

    last_message = models.OneToOneField(to='Message',
                                        on_delete=models.PROTECT,
                                        related_name='last_chat')

class Message(models.Model):
    id   = models.BigAutoField(primary_key=True)

    chat = models.ForeignKey(to='Chat',
                             on_delete=models.CASCADE)

    user = models.ForeignKey(to='accounts.User',
                             on_delete=models.PROTECT)

    text = models.CharField(max_length=200)

    date = models.DateTimeField()

问题是,为了创建一个新的聊天室,我将不得不插入一个新的chat对象和一个新的message对象。

但由于它们都互相引用,因此插入任何一个都会导致ForeignKey约束错误。

我该如何解决这个问题?延迟执行外键,直到我保存了两个

2 个答案:

答案 0 :(得分:1)

你说的问题是你有一个循环的关系。但我认为你不需要它; last_message字段是不必要的,因为您始终可以通过chat.message_set.order_by('date').last()查询最后一条消息。

答案 1 :(得分:1)

我建议使用post_save信号来设置上一条消息。首先,我们需要使last_message可以为空。

class Chat(models.Model):
    id   = models.BigAutoField(primary_key=True)

    subject      = models.CharField(max_length=200)

    last_message = models.OneToOneField(to='Message', null=True,
                                        on_delete=models.PROTECT,
                                        related_name='last_chat')
class Message(models.Model):
    ...

# example of signal
from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=Message)
def set_last_message(sender, instance, created, **kwargs):
    if created:
        Chat.objects.filter(id=instance.chat_id).update(last_message=instance)

# in your controller code
chat = Chat.objects.create(...)
Message.objects.create(chat=chat, ...) # so your last_message will be set on this line