60 for klassname in dir(model): |
60 for klassname in dir(model): |
61 klass = getattr(model, klassname) |
61 klass = getattr(model, klassname) |
62 if not isinstance(klass, TypeType): |
62 if not isinstance(klass, TypeType): |
63 continue |
63 continue |
64 |
64 |
|
65 # Create arrows to the parent classes |
65 for parent in klass.__bases__: |
66 for parent in klass.__bases__: |
66 G.add_edge(klassname, parent.__name__) |
67 G.add_edge(klassname, parent.__name__) |
67 edge = G.get_edge(klassname, parent.__name__) |
68 edge = G.get_edge(klassname, parent.__name__) |
68 edge.attr['arrowhead'] = "empty" |
69 edge.attr['arrowhead'] = "empty" |
69 |
70 |
70 refs = "" |
71 refs = "" |
71 attrs = "" |
72 attrs = "" |
72 for attrname in dir(klass): |
73 for attrname in dir(klass): |
73 attr = getattr(klass, attrname) |
74 attr = getattr(klass, attrname) |
|
75 |
|
76 # Is it an appengine datastore type? |
74 if type(attr) in google.appengine.ext.db.__dict__.values(): |
77 if type(attr) in google.appengine.ext.db.__dict__.values(): |
|
78 # References get arrows to the other class |
75 if isinstance(attr, google.appengine.ext.db.ReferenceProperty): |
79 if isinstance(attr, google.appengine.ext.db.ReferenceProperty): |
76 hasa = attr.reference_class.__name__ |
80 hasa = attr.reference_class.__name__ |
77 G.add_edge(hasa, klassname) |
81 G.add_edge(hasa, klassname) |
78 edge = G.get_edge(hasa, klassname) |
82 edge = G.get_edge(hasa, klassname) |
79 edge.attr['arrowhead'] = 'inv' |
83 edge.attr['arrowhead'] = 'inv' |
80 |
84 |
81 refs += "+ %s: %s\l" % (attrname, type(attr).__name__[:-8]) |
85 refs += "+ %s: %s\l" % (attrname, type(attr).__name__[:-8]) |
|
86 |
|
87 # Ignore back references |
82 elif isinstance(attr, google.appengine.ext.db._ReverseReferenceProperty): |
88 elif isinstance(attr, google.appengine.ext.db._ReverseReferenceProperty): |
83 pass |
89 pass |
84 else: |
90 else: |
85 attrs += "+ %s: %s\l" % (attrname, type(attr).__name__[:-8]) |
91 # Check that the property is not inherited for a parent class |
|
92 local = True |
|
93 for parent in klass.__bases__: |
|
94 if hasattr(parent, attrname): |
|
95 local = False |
|
96 |
|
97 if local: |
|
98 attrs += "+ %s: %s\l" % (attrname, type(attr).__name__[:-8]) |
86 label = "{%s|%s|%s}" % (klassname, attrs, refs) |
99 label = "{%s|%s|%s}" % (klassname, attrs, refs) |
87 |
|
88 print label |
|
89 |
100 |
90 G.add_node(klassname) |
101 G.add_node(klassname) |
91 node = G.get_node(klassname) |
102 node = G.get_node(klassname) |
92 node.attr['label'] = label |
103 node.attr['label'] = label |
93 node.attr['shape'] = "record" |
104 node.attr['shape'] = "record" |