在Django中一次提交中执行多个save()的最佳方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Django中一次提交中执行多个save()的最佳方法相关的知识,希望对你有一定的参考价值。
我是Django的新手,实际上是网络开发。已经搜索了一段时间,但还没有得到答案。
在我的项目中,当用户提交表单请求时,它将搜索某些网站,如果找到特定图像,它将下载图像并返回链接以供下载。
目前我有两个型号:
- 请求
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'))
- 图片
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:
- 收到请求时,使用基本信息save()到Request模型 - “Image ID”除外(它尚不可用),并将状态设置为“started”
- 进行搜索,下载图像,然后将()保存到图像模型 - 现在我有“图像ID”
- 使用“Image ID”信息更新Request实例,并将状态更新为“success”
选项B:
- 收到请求后立即搜索并下载图像,并将()保存到图像模型 - 现在我有“图像ID”
- 使用“图像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')
该解决方案可以通过两种方式完成:
- 您在相关字段中保存显式状态更改,手动创建新的SearchRequestStatus或..
- 你将
status
和status_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()的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章