DjangoGraphviz: modelviz.py

File modelviz.py, 3.5 KB (added by jimmy@…, 17 years ago)

Updated script off of trunk @ Jun 6 2007

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
25from django.contrib.contenttypes.generic import GenericRelation
26from django.template import Template, Context
27
28dot_template = """
29digraph {{ name }} {
30 fontname = "Helvetica"
31 fontsize = 8
32
33 node [
34 fontname = "Helvetica"
35 fontsize = 8
36 shape = "plaintext"
37 ]
38 edge [
39 fontname = "Helvetica"
40 fontsize = 8
41 ]
42
43 {% for model in models %}
44 {{ model.name }} [label=<
45 <TABLE BGCOLOR="palegoldenrod" BORDER="0" CELLBORDER="0" CELLSPACING="0">
46 <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="olivedrab4"
47 ><FONT FACE="Helvetica Bold" COLOR="white"
48 >{{ model.name }}</FONT></TD></TR>
49 {% for field in model.fields %}
50 <TR><TD ALIGN="LEFT" BORDER="0"
51 ><FONT FACE="Helvetica Bold">{{ field.name }}</FONT
52 ></TD>
53 <TD ALIGN="LEFT">{{ field.type }}</TD></TR>
54 {% endfor %}
55 </TABLE>
56 >]
57
58 {% for relation in model.relations %}
59 {{ model.name }} -> {{ relation.target }}
60 [label="{{ relation.type }}"] {{ relation.arrows }};
61 {% endfor %}
62 {% endfor %}
63}
64"""
65
66def generate_dot(app_label):
67 app = models.get_app(app_label)
68 graph = Context({
69 'name': '"%s"' % app.__name__,
70 'models': []
71 })
72
73 for appmodel in get_models(app):
74 model = {
75 'name': appmodel.__name__,
76 'fields': [],
77 'relations': []
78 }
79
80 # model attributes
81 def add_attributes():
82 model['fields'].append({
83 'name': field.name,
84 'type': type(field).__name__
85 })
86
87 for field in appmodel._meta.fields:
88 add_attributes()
89
90 if appmodel._meta.many_to_many:
91 for field in appmodel._meta.many_to_many:
92 add_attributes()
93
94 # relations
95 def add_relation(extras=""):
96 _rel = {
97 'target': field.rel.to.__name__,
98 'type': type(field).__name__,
99 'arrows': extras
100 }
101 if _rel not in model['relations']:
102 model['relations'].append(_rel)
103
104 for field in appmodel._meta.fields:
105 if isinstance(field, ForeignKey):
106 add_relation()
107 elif isinstance(field, OneToOneField):
108 add_relation("[arrowhead=none arrowtail=none]")
109
110 if appmodel._meta.many_to_many:
111 for field in appmodel._meta.many_to_many:
112 if isinstance(field, ManyToManyField):
113 add_relation("[arrowhead=normal arrowtail=normal]")
114 elif isinstance(field, GenericRelation):
115 add_relation(
116 '[style="dotted"] [arrowhead=normal arrowtail=normal]')
117 graph['models'].append(model)
118
119 t = Template(dot_template)
120 return t.render(graph)
121
122if __name__ == "__main__":
123 import sys
124 try:
125 app_label = sys.argv[1]
126 print generate_dot(app_label)
127 except IndexError:
128 print __doc__
Back to Top