在django';什么是orm?
例如,我使用多表继承来表示一个类节点,该类节点包含子类ConceptNode和DerivedNode。要确定我正在处理的节点类型并将函数调用向下分发到适当的子类,我通常必须像这样调用hasattr:在django';什么是orm?,django,django-models,django-orm,Django,Django Models,Django Orm,例如,我使用多表继承来表示一个类节点,该类节点包含子类ConceptNode和DerivedNode。要确定我正在处理的节点类型并将函数调用向下分发到适当的子类,我通常必须像这样调用hasattr: test_node = Node.objects.all()[0] if hasattr( test_node, "conceptnode"): test_node.conceptnode.myFunction() elif hasattr( test_node, "derivednode
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.")
我注意到这会导致多个db查询,这些查询加起来确实会减慢我编写的一些函数的速度
我尝试了另一种使用try…catch的方法,它不会减少查询的数量
test_node = Node.objects.all()[0]
try:
test_node.conceptnode.myFunction()
except ObjectDoesNotExist:
test_node.derivednode.myFunction()
我的主要问题是:django如何确定在这里执行哪些查询?我看不出hasattr是如何被转换成db查询的
另外,如果有人能建议一种更有效的方法来处理这个问题(特别是从查询计数的角度),那也太好了
编辑:要转储执行的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'}
其中第一个和第三个是获取原始节点对象。您有两个简单节点查找实例(限制1查询),因为您多次以列表的形式访问查询集
nodes = Node.objects.all()
nodes[0]
nodes[0]
触发两个查询,而:
node = Node.objects.all()[0]
node
node
触发一个。这一点乍看起来可能有点奇怪,但关键是要记住,Node.objects.all()
在您访问它之前不会进行计算(不会进行查询)
至于为什么单个对象查找会运行两个查询,您正在使用。如果您的模型中有此项:
class Node(models.Model):
pass
class ConceptNode(Node):
pass
Django将创建两个表,其中ConceptNode
行有一个父节点Node
您可能正在寻找的是一个,它允许您在多个类之间共享方法和属性,同时只为每个类使用一个表。只需将abstract=True
添加到父类meta:
class Node(models.Model):
class Meta:
abstract = True
最后,请注意,这两个查询几乎不需要花费时间,因此我不会太担心。@ColeMaclean-我将它们添加到问题中。谢谢Cole。我很确定Django正在查看表“nodes\u attribute”(其中属性可以是conceptnode或derivednode),并查看是否存在外键“node\u ptr\u id”与当前节点id相同的条目。我猜所有这些名称都是Django自动创建的,并在orm代码中使用,但我想确保我的思维模式是正确的。检查更新的答案,它现在应该涵盖了这一点。Django文档是你的朋友,尽管里面有太多东西,很难知道从哪里开始。