在 Django 中一次提交中执行多个 save() 的最佳方法
The best way to do multiple save() in one submit in Django
我是 Django 的新手,实际上是网络开发。找了一段时间了,还没找到答案。
在我的项目中,当用户提交表单请求时,它会搜索一些网站,如果找到特定的图片,它会下载图片并return link 进行下载。
目前我有两个模特:
请求
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)
只是想知道在提交请求时将 save() 保存到模型的最佳方法是什么。我想到的方法是:
选项A:
- 当接收到一个请求时,save() 到 Request model with basic
信息 - "Image ID" 除外(尚不可用),并设置
状态为 "started"
- 进行搜索,下载图片,然后save()到
图像模型 - 现在我有 "Image ID"
- 使用 "Image ID" 信息更新 Request 实例,并且
将状态更新为 "success"
选项 B:
请求成功后立即搜索并下载图片
收到,并将()保存到图像模型 - 现在我有 "Image ID"
Save() 到带有 "Image ID" 的请求模型 - 这是一个新的
插入 activity.
哪种方法最好?或者还有其他更好的方法吗?
此外,对于这种情况,有没有使用 Django 的 "transaction" 功能的建议?我不喜欢它用于我的小项目 - 只是不想让它太复杂。
我会选择选项 A,我 强烈建议您重命名 "Request" 模型,例如:"SearchRequest" Request
是 django 世界中非常具体的东西,如果你向它添加一个新的上下文,你很快就会很困惑。
触发SearchRequest
时可以保存创建时间,STARTED
中的状态,然后进行研究。在研究过程中可能会出现问题,因此最好将图像搜索包装在 try/except 上。然后,您可以使用 FAILED
保存状态以及出现问题时的原因。这回答了关于原子事务的问题,你不需要那个。
另外一个建议,将图片名称移到Image模型上,SearchRequest可以从相关图片中获取图片名称。
对 SearchRequest 的一项改进是将 Status 保存为相关模型,以便您可以在搜索过程中重建状态的变化。
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(发件人,实例,**kwargs):
current_status = SearchRequest.objects.filter(search=instance).first()
如果不是 current_status 或 current_status.status != instance.status:
SearchRequestStatus.objects.create(搜索=实例,
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 的新手,实际上是网络开发。找了一段时间了,还没找到答案。
在我的项目中,当用户提交表单请求时,它会搜索一些网站,如果找到特定的图片,它会下载图片并return link 进行下载。
目前我有两个模特:
请求
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)
只是想知道在提交请求时将 save() 保存到模型的最佳方法是什么。我想到的方法是:
选项A:
- 当接收到一个请求时,save() 到 Request model with basic 信息 - "Image ID" 除外(尚不可用),并设置 状态为 "started"
- 进行搜索,下载图片,然后save()到 图像模型 - 现在我有 "Image ID"
- 使用 "Image ID" 信息更新 Request 实例,并且 将状态更新为 "success"
选项 B:
请求成功后立即搜索并下载图片 收到,并将()保存到图像模型 - 现在我有 "Image ID"
Save() 到带有 "Image ID" 的请求模型 - 这是一个新的 插入 activity.
哪种方法最好?或者还有其他更好的方法吗?
此外,对于这种情况,有没有使用 Django 的 "transaction" 功能的建议?我不喜欢它用于我的小项目 - 只是不想让它太复杂。
我会选择选项 A,我 强烈建议您重命名 "Request" 模型,例如:"SearchRequest" Request
是 django 世界中非常具体的东西,如果你向它添加一个新的上下文,你很快就会很困惑。
触发SearchRequest
时可以保存创建时间,STARTED
中的状态,然后进行研究。在研究过程中可能会出现问题,因此最好将图像搜索包装在 try/except 上。然后,您可以使用 FAILED
保存状态以及出现问题时的原因。这回答了关于原子事务的问题,你不需要那个。
另外一个建议,将图片名称移到Image模型上,SearchRequest可以从相关图片中获取图片名称。
对 SearchRequest 的一项改进是将 Status 保存为相关模型,以便您可以在搜索过程中重建状态的变化。
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(发件人,实例,**kwargs): current_status = SearchRequest.objects.filter(search=instance).first() 如果不是 current_status 或 current_status.status != instance.status: SearchRequestStatus.objects.create(搜索=实例, 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)