DjangoGraphviz: modelviz.py

File modelviz.py, 3.5 KB (added by jimmy@…, 8 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