2 """Django model to DOT (Graphviz) converter
3 by Antonio Cavedoni <antonio@cavedoni.org>
5 Make sure your DJANGO_SETTINGS_MODULE is set to your project or
6 place this script in the same directory of the project and call
9 $ python modelviz.py [-h] [-d] <app_label> ... <app_label> > <filename>.dot
10 $ dot <filename>.dot -Tpng -o <filename>.png
14 show this help message and exit.
17 don't show the class member fields.
21 __license__
= "Python"
22 __author__
= "Antonio Cavedoni <http://cavedoni.com/>"
24 "Stefano J. Attardi <http://attardi.org/>",
25 "limodou <http://www.donews.net/limodou/>",
27 "Andre Campos <cahenan@gmail.com>",
28 "Justin Findlay <jfindlay@gmail.com>",
33 from django
.core
.management
import setup_environ
40 setup_environ(settings
)
42 from django
.template
import Template
, Context
43 from django
.db
import models
44 from django
.db
.models
import get_models
45 from django
.db
.models
.fields
.related
import \
46 ForeignKey
, OneToOneField
, ManyToManyField
49 from django
.db
.models
.fields
.generic
import GenericRelation
51 from django
.contrib
.contenttypes
.generic
import GenericRelation
55 fontname = "Helvetica"
59 fontname = "Helvetica"
64 fontname = "Helvetica"
71 {% for model in models %}
72 {% for relation in model.relations %}
73 {{ relation.target }} [label=<
74 <TABLE BGCOLOR="palegoldenrod" BORDER="0" CELLBORDER="0" CELLSPACING="0">
75 <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="olivedrab4"
76 ><FONT FACE="Helvetica Bold" COLOR="white"
77 >{{ relation.target }}</FONT></TD></TR>
80 {{ model.name }} -> {{ relation.target }}
81 [label="{{ relation.name }}"] {{ relation.arrows }};
85 {% for model in models %}
86 {{ model.name }} [label=<
87 <TABLE BGCOLOR="palegoldenrod" BORDER="0" CELLBORDER="0" CELLSPACING="0">
88 <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="olivedrab4"
89 ><FONT FACE="Helvetica Bold" COLOR="white"
90 >{{ model.name }}</FONT></TD></TR>
92 {% if not disable_fields %}
93 {% for field in model.fields %}
94 <TR><TD ALIGN="LEFT" BORDER="0"
95 ><FONT {% if field.blank %}COLOR="#7B7B7B" {% endif %}FACE="Helvetica Bold">{{ field.name }}</FONT
98 ><FONT {% if field.blank %}COLOR="#7B7B7B" {% endif %}FACE="Helvetica Bold">{{ field.type }}</FONT
111 def generate_dot(app_labels
, **kwargs
):
112 disable_fields
= kwargs
.get('disable_fields', False)
116 for app_label
in app_labels
:
117 app
= models
.get_app(app_label
)
119 'name': '"%s"' % app
.__name
__,
120 'disable_fields': disable_fields
,
124 for appmodel
in get_models(app
):
126 'name': appmodel
.__name
__,
132 def add_attributes():
133 model
['fields'].append({
135 'type': type(field
).__name
__,
139 for field
in appmodel
._meta
.fields
:
142 if appmodel
._meta
.many_to_many
:
143 for field
in appmodel
._meta
.many_to_many
:
147 def add_relation(extras
=""):
149 'target': field
.rel
.to
.__name
__,
150 'type': type(field
).__name
__,
154 if _rel
not in model
['relations']:
155 model
['relations'].append(_rel
)
157 for field
in appmodel
._meta
.fields
:
158 if isinstance(field
, ForeignKey
):
160 elif isinstance(field
, OneToOneField
):
161 add_relation("[arrowhead=none arrowtail=none]")
163 if appmodel
._meta
.many_to_many
:
164 for field
in appmodel
._meta
.many_to_many
:
165 if isinstance(field
, ManyToManyField
):
166 add_relation("[arrowhead=normal arrowtail=normal]")
167 elif isinstance(field
, GenericRelation
):
169 '[style="dotted"] [arrowhead=normal arrowtail=normal]')
170 graph
['models'].append(model
)
172 t
= Template(body_template
)
173 dot
+= '\n' + t
.render(graph
)
175 dot
+= '\n' + tail_template
181 opts
, args
= getopt
.getopt(sys
.argv
[1:], "hd",
182 ["help", "disable_fields"])
183 except getopt
.GetoptError
, error
:
192 for opt
, arg
in opts
:
193 if opt
in ("-h", "--help"):
196 if opt
in ("-d", "--disable_fields"):
197 kwargs
['disable_fields'] = True
198 print generate_dot(args
, **kwargs
)
200 if __name__
== "__main__":