gpt4 book ai didi

python - 如果对象已在 Django 中删除,如何更新对象或保释

转载 作者:行者123 更新时间:2023-12-03 15:00:05 25 4
gpt4 key购买 nike

我有一个 Django 应用程序将对象保存到数据库和一个 celery 任务,它定期对其中一些对象进行一些处理。问题是用户可以在 celery 任务选择对象进行处理之后,但在 celery 任务实际完成处理并保存它之前删除该对象。所以当 celery 任务调用 .save() 时,即使用户删除了该对象,该对象也会重新出现在数据库中。当然,这对用户来说真的很可怕。

所以这是一些显示问题的代码:

def my_delete_view(request, pk):
thing = Thing.objects.get(pk=pk)
thing.delete()
return HttpResponseRedirect('yay')

@app.task
def my_periodic_task():
things = get_things_for_processing()
# if the delete happens anywhere between here and the .save(), we're hosed
for thing in things:
process_thing(thing) # could take a LONG time
thing.save()

我想尝试通过添加一个原子块和一个事务来修复它,以在保存之前测试该对象是否确实存在:
@app.task
def my_periodic_task():
things = Thing.objects.filter(...some criteria...)
for thing in things:
process_thing(thing) # could take a LONG time
try:
with transaction.atomic():
# just see if it still exists:
unused = Thing.objects.select_for_update().get(pk=thing.pk)
# no exception means it exists. go ahead and save the
# processed version that has all of our updates.
thing.save()
except Thing.DoesNotExist:
logger.warning("Processed thing vanished")

这是做这种事情的正确模式吗?我的意思是,我会在生产环境中运行它后的几天内发现它是否有效,但是很高兴知道是否有任何其他被广泛接受的模式来完成这类事情。

我真正想要的是能够更新一个对象,如果它仍然存在于数据库中。我对来自 process_thing 的用户编辑和编辑之间的竞争感到满意,我总是可以抛出 refresh_from_db就在 process_thing 之前最大限度地减少用户编辑丢失的时间。但是我绝对不能让对象在用户删除它们后重新出现。

最佳答案

如果你在处理celery任务的时候开启一个事务,你应该避免这样的问题:

@app.task
@transaction.atomic
def my_periodic_task():
things = get_things_for_processing()
# if the delete happens anywhere between here and the .save(), we're hosed
for thing in things:
process_thing(thing) # could take a LONG time
thing.save()

有时,您想向前端报告您正在处理数据,因此您可以添加 select_for_update()到您的查询集(最有可能在 get_things_for_processing 中),然后在负责删除的代码中,您需要在 db 报告特定记录被锁定时处理错误。

关于python - 如果对象已在 Django 中删除,如何更新对象或保释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37234977/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com