例如,我对具有子类 ConceptNode 和 DerivedNode 的类 Node 使用多表继承。为了确定我正在处理的节点类型并将函数调用分发到适当的子类,我经常必须像这样调用 hasattr:
test_node = Node.objects.all()[0]
if hasattr( test_node, "conceptnode"):
test_node.conceptnode.myFunction()
elif hasattr( test_node, "derivednode"):
test_node.derivednode.myFunction()
else:
raise Exception("Not a valid type.")
我注意到这会导致多个数据库查询,这加起来确实会减慢我编写的某些函数的速度。
我尝试了另一种使用 try...catch 的方法,它不会减少查询的数量。
test_node = Node.objects.all()[0]
try:
test_node.conceptnode.myFunction()
except ObjectDoesNotExist:
test_node.derivednode.myFunction()
我的主要问题是:django 如何确定在这里执行哪些查询?我看不到 hasattr 是如何被翻译成数据库查询的。
此外,如果有人可以建议一种更有效的方法来处理这个问题(尤其是从查询计数的角度来看),那也太好了!
编辑:为了转储执行的 sqlite 查询,我执行了以下操作:
from django.db import connection
from django import db
db.reset_queries()
hasattr(nds[0],'conceptnode')
hasattr(nds[0],'derivednode')
connection.queries
我得到了以下结果:
{'sql': u'SELECT "nodes_node"."id", "nodes_node"."name", "nodes_node"."description", "nodes_node"."node_tree_id", "nodes_node"."unique_name", "nodes_node"."last_updated_timestamp", "nodes_node"."order", "nodes_node"."data_json", "nodes_node"."data_json_synchronized" FROM "nodes_node" LIMIT 1', 'time': '0.001'}
{'sql': u'SELECT "nodes_node"."id", "nodes_node"."name", "nodes_node"."description", "nodes_node"."node_tree_id", "nodes_node"."unique_name", "nodes_node"."last_updated_timestamp", "nodes_node"."order", "nodes_node"."data_json", "nodes_node"."data_json_synchronized", "nodes_conceptnode"."node_ptr_id", "nodes_conceptnode"."node_parent_id" FROM "nodes_conceptnode" INNER JOIN "nodes_node" ON ("nodes_conceptnode"."node_ptr_id" = "nodes_node"."id") WHERE "nodes_conceptnode"."node_ptr_id" = 1 ', 'time': '0.000'}
{'sql': u'SELECT "nodes_node"."id", "nodes_node"."name", "nodes_node"."description", "nodes_node"."node_tree_id", "nodes_node"."unique_name", "nodes_node"."last_updated_timestamp", "nodes_node"."order", "nodes_node"."data_json", "nodes_node"."data_json_synchronized" FROM "nodes_node" LIMIT 1', 'time': '0.001'}
{'sql': u'SELECT "nodes_node"."id", "nodes_node"."name", "nodes_node"."description", "nodes_node"."node_tree_id", "nodes_node"."unique_name", "nodes_node"."last_updated_timestamp", "nodes_node"."order", "nodes_node"."data_json", "nodes_node"."data_json_synchronized", "nodes_derivednode"."node_ptr_id", "nodes_derivednode"."node_source_id", "nodes_derivednode"."node_target_id" FROM "nodes_derivednode" INNER JOIN "nodes_node" ON ("nodes_derivednode"."node_ptr_id" = "nodes_node"."id") WHERE "nodes_derivednode"."node_ptr_id" = 1 ', 'time': '0.000'}
其中第一个和第三个是获取原始节点对象。