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

问题描述 投票:0回答:1

我是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的“事务”功能这样的场景?我不喜欢它用于我的小项目 - 只是不想让它变得太复杂。

django save multiple-tables
1个回答
1
投票

我会选择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)
© www.soinside.com 2019 - 2024. All rights reserved.