DjangoGraphviz: modelviz.2.py

File modelviz.2.py, 3.5 KB (added by QingFeng, 17 years ago)

Django Trunk GenericRelation Modify

Line 
1#!/usr/bin/env python
2"""Django model to DOT (Graphviz) converter
3by Antonio Cavedoni <antonio@cavedoni.org>
4
5Make sure your DJANGO_SETTINGS_MODULE is set to your project and call
6the script like this:
7
8$ python modelviz.py <app_label> > <filename>.dot
9"""
10
11__version__ = "0.6"
12__svnid__ = "$Id$"
13__license__ = "Python"
14__author__ = "Antonio Cavedoni <http://cavedoni.com/>"
15__contributors__ = [
16 "Stefano J. Attardi <http://attardi.org/>",
17 "limodou <http://www.donews.net/limodou/>",
18 "Carlo C8E Miron"
19 ]
20
21from django.db import models
22from django.db.models import get_models
23from django.db.models.fields.related import \
24 ForeignKey, OneToOneField, ManyToManyField
25try:
26 from django.db.models.fields.generic import GenericRelation
27except ImportError:
28 from django.contrib.contenttypes.generic import GenericRelation
29from django.template import Template, Context
30
31dot_template = """
32digraph {{ name }} {
33 fontname = "Helvetica"
34 fontsize = 8
35
36 node [
37 fontname = "Helvetica"
38 fontsize = 8
39 shape = "plaintext"
40 ]
41 edge [
42 fontname = "Helvetica"
43 fontsize = 8
44 ]
45
46 {% for model in models %}
47 {{ model.name }} [label=<
48 <TABLE BGCOLOR="palegoldenrod" BORDER="0" CELLBORDER="0" CELLSPACING="0">
49 <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="olivedrab4"
50 ><FONT FACE="Helvetica Bold" COLOR="white"
51 >{{ model.name }}</FONT></TD></TR>
52 {% for field in model.fields %}
53 <TR><TD ALIGN="LEFT" BORDER="0"
54 ><FONT FACE="Helvetica Bold">{{ field.name }}</FONT
55 ></TD>
56 <TD ALIGN="LEFT">{{ field.type }}</TD></TR>
57 {% endfor %}
58 </TABLE>
59 >]
60
61 {% for relation in model.relations %}
62 {{ model.name }} -> {{ relation.target }}
63 [label="{{ relation.type }}"] {{ relation.arrows }};
64 {% endfor %}
65 {% endfor %}
66}
67"""
68
69def generate_dot(app_label):
70 app = models.get_app(app_label)
71 graph = Context({
72 'name': '"%s"' % app.__name__,
73 'models': []
74 })
75
76 for appmodel in get_models(app):
77 model = {
78 'name': appmodel.__name__,
79 'fields': [],
80 'relations': []
81 }
82
83 # model attributes
84 def add_attributes():
85 model['fields'].append({
86 'name': field.name,
87 'type': type(field).__name__
88 })
89
90 for field in appmodel._meta.fields:
91 add_attributes()
92
93 if appmodel._meta.many_to_many:
94 for field in appmodel._meta.many_to_many:
95 add_attributes()
96
97 # relations
98 def add_relation(extras=""):
99 _rel = {
100 'target': field.rel.to.__name__,
101 'type': type(field).__name__,
102 'arrows': extras
103 }
104 if _rel not in model['relations']:
105 model['relations'].append(_rel)
106
107 for field in appmodel._meta.fields:
108 if isinstance(field, ForeignKey):
109 add_relation()
110 elif isinstance(field, OneToOneField):
111 add_relation("[arrowhead=none arrowtail=none]")
112
113 if appmodel._meta.many_to_many:
114 for field in appmodel._meta.many_to_many:
115 if isinstance(field, ManyToManyField):
116 add_relation("[arrowhead=normal arrowtail=normal]")
117 elif isinstance(field, GenericRelation):
118 add_relation(
119 '[style="dotted"] [arrowhead=normal arrowtail=normal]')
120 graph['models'].append(model)
121
122 t = Template(dot_template)
123 return t.render(graph)
124
125if __name__ == "__main__":
126 import sys
127 try:
128 app_label = sys.argv[1]
129 print generate_dot(app_label)
130 except IndexError:
131 print __doc__
Back to Top