我就废话不多说了,大家还是直接看代码吧!
# 因为此时为yaml模板,而且只抓取node port,所以这样处理效率快 content_dict = parse_yaml(content.replace("{{", "").replace("}}", "")) if 'service' in content_dict.keys(): # 记录本次yaml里所有的node_port,并更新到数据库 now_app_list = [] for service_item in content_dict['service']: for port_item in service_item['port']: if 'nodePort' in port_item.keys(): node_port = int(port_item['nodePort']) if 30000 <= node_port <= 32000: # 这里判断比较复杂,如果端口有,而且app相同,不更新。如果端口有,app不一样,报冲突。如果端口没有,可插入。 now_app_list.append(node_port) try: AppPort.objects.get(node_port=node_port, app=app) pass except AppPort.DoesNotExist: try: AppPort.objects.get(node_port=node_port) messages.info(self.request, 'nodeport{}端口冲突!'.format(node_port)) return HttpResponseRedirect(reverse_lazy("app:yaml_edit", kwargs=self.kwargs)) except AppPort.DoesNotExist: name = '{}-{}'.format(app.name, node_port) AppPort.objects.create( name=name, app=app, node_port=node_port ) else: messages.info(self.request, 'nodeport{}端口不在指定范围内(30000-~32000)!'.format(node_port)) return HttpResponseRedirect(reverse_lazy("app:yaml_edit", kwargs=self.kwargs)) # 取出AppPort里所有此app的node_port,多余的要清除。 all_app_list = AppPort.objects.filter(app=app).values_list('node_port', flat=True) if all_app_list: # 取交集,也就是数据库里多余的端口列表 diff_list = [x for x in all_app_list if x not in now_app_list] if diff_list: AppPort.objects.filter(node_port__in=diff_list).delete()
感觉上面这段代码,应用的技术点蛮多的,作个记录。
包括其node port的管理思想,提取技巧。
orm的列表扁平化,列表交集,批量删除
补充知识:Django 在异常捕获中进行数据库保存,保存后将异常再抛出
需求:
当我检查配额时,如果配额不足,我需要将订单状态改为5,然后再将原有异常抛出
一:最初做法
try: self.check_quota_enough(create_form) # 检查配额 except Exception as e: self.object.state = 5 self.object.save() raise e
存在问题:django默认开启了事务,因此我保存订单状态后,再抛异常时没有任何问题
但当我查询数据库订单状态时,发现异常抛出之前订单改变的状态已经丢失
二:优化,使用装饰器,手动关闭事务
# 在dispatch方法上增加装饰器,关闭事务 class xxxxxxxx(): @method_decorator(transaction.non_atomic_requests) def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) def form_valid(self, form): ... ... try: self.check_quota_enough(create_form) # 检查配额 except Exception as e: self.object.state = 5 self.object.save() raise e
该方法可以解决上述问题
但该方法对整个视图有效,如果在视图其他地方需要用到事务的一致性,则显然不合理
二:优化,定义事务保存点,在局部控制事务一致性
class xxxxxxxx(): def form_valid(self, form): ... ... sid = transaction.savepoint() # 定义事务保存点 try: self.check_quota_enough(create_form) except QuotaNotEnough as e: self.object.state = 5 self.object.save() transaction.savepoint_commit(sid) return self.render_to_json_response(result=False, messages=str(e))
a.save():此处保存了数据
sid = transaction.savepoint():设置保存点
b.save():此处再次保存了数据
接下来就是逻辑处理:如果满足xxxxxxxx条件,则手动提交,此时a.save()和b.save()保存的数据都会生效。
如果不满足xxxxxxxx条件,则执行事务回滚,此时我们定义的保存点之前的a.save()数据不会收到影响,但在保存点之后的b.save()的数据将会回滚。
所以我们可以通过调整保存点的位置,实现我们的需求。
以上这篇django中嵌套的try-except实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持小牛知识库。
问题内容: 我知道,如果我想重新引发异常,我会在相应的块中简单地使用没有参数的方法。但是给定一个嵌套的表达式 如何在不破坏堆栈跟踪的情况下重新筹集?在这种情况下,仅此一项会重新提高最近的筹码。还是我应该重构代码来避免此问题? 问题答案: 从Python 3开始,回溯存储在异常中,因此(大多数)正确的事情很简单: 产生的追溯将包括在处理过程中发生的其他通知(由于位于内部)。这具有误导性,因为实际发生
主要内容:获取特定异常的有关信息Python 中,用 语句块捕获并处理异常,其基本语法结构如下所示: try: 可能产生异常的代码块 except [ (Error1, Error2, ... ) [as e] ]: 处理异常的代码块1 except [ (Error3, Error4, ... ) [as e] ]: 处理异常的代码块2 except [Exception]: 处理其它异常 该
问题内容: 我正在编写自己的容器,该容器需要通过属性调用来访问内部的字典。容器的典型用法如下: 我知道写这样的东西可能很愚蠢,但这就是我需要提供的功能。我正在考虑通过以下方式实现此目的: 我不确定嵌套的try / except块是否是一个好习惯,所以另一种方法是使用and : 或者使用其中之一,然后尝试使用catch块,如下所示: 哪个选项最适合pythonic和优雅? 问题答案: 您的第一个例子
Python 异常处理机制还提供了一个 finally 语句,通常用来为 try 块中的程序做扫尾清理工作。 注意,和 else 语句不同,finally 只要求和 try 搭配使用,而至于该结构中是否包含 except 以及 else,对于 finally 不是必须的(else 必须和 try except 搭配使用)。 在整个异常处理机制中, finally 语句的功能是:无论 try 块是否
在原本的 结构的基础上, Python 异常处理机制还提供了一个 else 块,也就是原有 try except 语句的基础上再添加一个 else 块,即 结构。 使用 else 包裹的代码,只有当 try 块没有捕获到任何异常时,才会得到执行;反之,如果 try 块捕获到异常,即便调用对应的 except 处理完异常,else 块中的代码也不会得到执行。 举个例子: 可以看到,在原有 try e
我们尝试读取用户的一段输入。按Ctrl-d,看一下会发生什么。 >>> s = raw_input('Enter something --> ') Enter something --> Traceback (most recent call last): File "<stdin>", line 1, in ? EOFError Python引发了一个称为EOFError的错误,这个错误基本