= Converting Django models into Graphviz DOT files = Inspired by [http://www.hackdiary.com/archives/000093.html this nice hack by Matt Biddulph] I set out to create a similar thing for Django models. Below is an initial implementation, and here are some results generated with the OS X version of Graphviz: * [http://cavedoni.com/2006/08/camera-001.dot generated dot file]: resulting image in [http://cavedoni.com/2006/08/camera-001.pdf PDF] * [http://cavedoni.com/2006/08/mincer-001.dot generated dot file]: resulting image in [http://cavedoni.com/2006/08/mincer-001.pdf PDF] You might also be interested in [http://www.exit66.com/diagram.zip this Django app by Andrew Barilla ] from which I borrowed some ideas, that displays the graphviz results directly from the web. {{{ #!python #!/usr/bin/python """Django model to DOT (Graphviz) converter by Antonio Cavedoni Make sure your DJANGO_SETTINGS_MODULE is set to your project and call the script like this: $ python modelviz.py > .dot Example: $ python modelviz.py camera > foo.dot """ from django.db import models from django.db.models import get_models from django.db.models.fields.related import \ ForeignKey, OneToOneField, ManyToManyField def generate_dot(app_label): app = models.get_app(app_label) print "digraph %s {" % ('"' + app.__name__ + '"') print """ fontname = "Helvetica" fontsize = 8 node [ fontname = "Helvetica" fontsize = 8 shape = "record" ] edge [ fontname = "Helvetica" fontsize = 8 ] """ for o in get_models(app): nodes = [] nodes.append(""" %s [ label = "{%s | """ % (o.__name__, o.__name__)) # members for field in o._meta.fields: nodes.append("%s : %s\\l" % (field.name, type(field).__name__)) for field in o._meta.many_to_many: nodes.append("%s : %s\\l" % (field.name, type(field).__name__)) nodes.append(""" }"\n]\n""") print "".join(nodes) # relations rel = [] for field in o._meta.fields: if isinstance(field, ForeignKey): _rel = ' %s -> %s [label="%s"];' % \ (o.__name__, field.rel.to.__name__, type(field).__name__) if _rel not in rel: rel.append(_rel) for field in o._meta.many_to_many: if isinstance(field, ManyToManyField): _rel = ' %s -> %s [label="%s"] [arrowhead=normal arrowtail=normal];' % \ (o.__name__, field.rel.to.__name__, type(field).__name__) if _rel not in rel: rel.append(_rel) print "\n".join(rel) print "}" if __name__ == "__main__": import sys app_label = sys.argv[1] generate_dot(app_label) }}}