Python 使用transaction.atomic回滚递归表单验证+;拯救
我想递归地验证和保存json“树”(Python 使用transaction.atomic回滚递归表单验证+;拯救,python,django,recursion,Python,Django,Recursion,我想递归地验证和保存json“树”(process\u response下面的函数)。如果树中的任何叶子无效,我想回滚到目前为止保存的所有叶子。以下是我的方法示例: @staticmethod def process_response(post_data): """ brief pseudocode function to illustrate resursive form.save() """ if is_leaf is True: if not form.is
process\u response
下面的函数)。如果树中的任何叶子无效,我想回滚到目前为止保存的所有叶子。以下是我的方法示例:
@staticmethod
def process_response(post_data):
""" brief pseudocode function to illustrate resursive form.save() """
if is_leaf is True:
if not form.is_valid():
return HttpResponse(status=400)
else:
form.save(post_data)
return HttpResponse(status=200)
else: # is not a leaf, so must be a branch
for child_data in post_data.children
result = MyClass.process_response(child_data)
if result.status_code != 200:
return result
def post(self, request, *args, **kwargs):
post_data = process_post_data(request) # json decoding, validation, etc
with transaction.atomic():
try:
result = MyClass.process_response(post_data)
if result.status_code != 200:
raise DatabaseError
except:
return result
return result
在
transaction.atomic
中包装对process\u response
的调用并引发DatabaseError
是否允许我这样做?或者有没有其他更好的方法来验证和保存“树”结构中的数据?为每个叶调用form.save()
,这一事实似乎很奇怪:通常情况下,您会验证整个内容一次(递归或不递归),然后保存一次。惯用的方法是在自定义表单类上结合使用validate()
和save()
方法
也就是说,我假设您确实需要某种递归数据库保存。在这种情况下:
子句用于try
事务atomic()
- 将
保留到数据库中。使用更合适的方法,如DatabaseError
或ValueError
ValidationError
- 将
留给调用函数,没有理由将这样的关注点混入递归函数中HttpResponse
def validate_and _save(data):
if is_leaf:
if not valid:
raise ValueError()
else:
save_leaf()
else:
for child in children:
validate_and _save(child)
def post(self, request, *args, **kwargs):
post_data = process_post_data(request)
try:
with transaction.atomic():
validate_and_save(post_data)
except ValueError:
return HttpResponse(status=400)
else:
return HttpResponse(status=200)
如果抛出的异常不是
DatabaseError
或其子类,transaction.atomic是否回滚?关于第一次验证和第二次保存,我实际上事先不知道树有多大(就我而言,它只有一个分支深,但我不知道有多少分支),因此在验证时我必须记录树的结构。此外,并非所有叶片都是相同的型号
类型。我认为递归保存在这种情况下更具可读性。例如,请参阅关于在atomic()
中避免捕获异常的部分:示例使用DatabaseError
subclasses@Escher:是,事务在任何异常时回滚。