我有课程Node
,Leaf (Node)
如下所示:
class Node (db.Model):
__mapper_args__ = {'polymorphic_identity':'node', 'polymorphic_on':'type'}
id = db.Column (db.Integer, primary_key=True)
type = db.Column ('type', db.String (16))
root_id = db.Column (db.Integer, db.ForeignKey (id))
nodes = db.relationship ('Node',
cascade='all', lazy='dynamic',
primaryjoin='Node.root_id==Node.id',
backref=db.backref('root', remote_side=id))
leafs = db.relationship ('Leaf',
cascade='all', lazy='dynamic',
primaryjoin='Leaf.root_id==Node.id')
def __init__ (self, root):
self.root = root
和
class Leaf (Node):
__mapper_args__ = {'polymorphic_identity': 'leaf'}
leaf_id = db.Column (db.Integer, db.ForeignKey ('node.id'), primary_key=True)
def __init__ (self, root):
super (Leaf, self).__init__ (root)
具有以下属性(摘自我的测试):
def test_polymorphic (self):
base_node, leaf_of_base, node_of_base, leaf_of_node = self.create ()
self.commit ([base_node, leaf_of_base, node_of_base, leaf_of_node])
leaf, node = base_node.nodes.all ()
self.assertEqual (type (leaf), Leaf)
self.assertTrue (isinstance (leaf, Node))
self.assertTrue (isinstance (leaf, Leaf))
self.assertEqual (type (node), Node)
self.assertTrue (isinstance (node, Node))
self.assertFalse (isinstance (node, Leaf))
所以Node.nodes
包括叶子对象(这是我想要的),并且只Node.leafs
产生叶子对象(这也很好)。
现在,我想介绍一下Node.nodes_except_leafs
,我确实喜欢:
class Node (db.Model):
...
nodes_except_leafs = property (lambda self: self.nodes.filter_by (type='node'))
这实际上可行,但我认为这不是最好的解决方案,因为使用这种方法,我会错过例如以下类型的节点:
class NodeEx (Node):
__mapper_args__ = {'polymorphic_identity': 'nodeex'}
nodex_id = db.Column (db.Integer, db.ForeignKey ('node.id'), primary_key=True)
def __init__ (self, root):
super (NodeEx, self).__init__ (root)
因为Node.nodes.filter_by (type='node')
会错过所有NodeEx
带有NodeEx.type == 'nodeex'
.
Node.nodes_except_leafs
对于返回所有非叶或叶派生对象(可能从 的子类派生),有什么更好的解决方案Node
?谢谢。