在Django中一次提交中执行多个save()的最佳方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Django中一次提交中执行多个save()的最佳方法相关的知识,希望对你有一定的参考价值。

我是Django的新手,实际上是网络开发。已经搜索了一段时间,但还没有得到答案。

在我的项目中,当用户提交表单请求时,它将搜索某些网站,如果找到特定图像,它将下载图像并返回链接以供下载。

目前我有两个型号:

  1. 请求 class Request(models.Model): create_time = models.DateTimeField('create time', auto_now_add=True) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET('unknown')) image_name = models.CharField(max_length=48) image = models.ForeignKey(Image, on_delete=models.SET('unknown'))
  2. 图片 class Image(models.Model): add_time = models.DateTimeField('add time', auto_now_add=True) image_source = models.CharField(max_length=48) image_size = models.CharField(max_length=48)

只是想知道在提交请求时将()保存到模型的最佳方法是什么。我想到的方法是:

选项A:

  1. 收到请求时,使用基本信息save()到Request模型 - “Image ID”除外(它尚不可用),并将状态设置为“started”
  2. 进行搜索,下载图像,然后将()保存到图像模型 - 现在我有“图像ID”
  3. 使用“Image ID”信息更新Request实例,并将状态更新为“success”

选项B:

  1. 收到请求后立即搜索并下载图像,并将()保存到图像模型 - 现在我有“图像ID”
  2. 使用“图像ID”将()保存到请求模型 - 这是一个新的插入活动。

这是最好的方法吗?或者还有其他更好的方法吗?

此外,任何建议使用Django的“事务”功能这样的场景?我不喜欢它用于我的小项目 - 只是不想让它变得太复杂。

答案

我会选择A选项,我强烈建议你将“请求”模型重命名为不同的东西,例如:“SearchRequest”Request在django世界中是非常具体的,如果你添加一个新的上下文,你将会很快就会很困惑。

SearchRequest被触发时,你可以保存创建时间,在STARTED中的状态,然后进行研究。在研究过程中出现问题所以如果你在try / except上搜索图像会更好。然后,您可以使用FAILED保存状态以及出现问题的原因。这回答了关于原子事务的问题,你不需要那样做。

另一个建议是,在Image模型上移动图像的名称,SearchRequest可以从相关图像中获取图像名称。

SearchRequest的改进是将状态保存为相关模型,以便您可以在搜索期间重建状态的更改。

class SearchRequestStatus(models.Model):
    create_time = models.DateTimeField('create time', auto_now_add=True)
    status = models.CharField(max_length=48)
    detail = models.CharField(max_length=256)
    search = models.ForeignKey(SearchRequest, on_delete=models.CASCADE, related_name='statuses')

该解决方案可以通过两种方式完成:

  1. 您在相关字段中保存显式状态更改,手动创建新的SearchRequestStatus或..
  2. 你将statusstatus_detail保存在SearchRequest中,保存信号将获取更改并使用接收器自动创建SearchRequestStatus。 (见:https://docs.djangoproject.com/en/2.1/topics/signals/) @receiver(signals.post_save,sender = SearchRequest,weak = False,dispatch_uid =“_ update_search_request_status_history”)def _update_search_request_status_history(sender,instance,** kwargs):current_status = SearchRequest.objects.filter(search = instance).first()if not current_status或current_status.status!= instance.status:SearchRequestStatus.objects.create(search = instance,status = instance.status,status_detail = instance.status_detail)

当然,您必须将字段添加到SearchRequest模型中,并添加STATUSES元组以限制状态选择

status = models.CharField(max_length=15, choices=STATUSES.items(), default=`STARTED`)
status_detail = models.CharField(max_length=80, null=True, blank=True)

以上是关于在Django中一次提交中执行多个save()的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Django 中一次将多个对象添加到 ManyToMany 关系?

如何在 Prometheus 中一次调用执行多个查询

在 Mongoose 中一次执行多个查询

如何在 Firestore 中一次创建/更新多个文档

在 oracle 中一次捕获多个异常

在 django 管理面板中一次添加多条记录