Changeset 73
- Timestamp:
- 06/21/07 17:32:52 (19 months ago)
- Files:
-
- 1 modified
-
django/trunk/utils/modelviz.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
django/trunk/utils/modelviz.py
r51 r73 3 3 by Antonio Cavedoni <antonio@cavedoni.org> 4 4 5 Make sure your DJANGO_SETTINGS_MODULE is set to your project and call 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 6 7 the script like this: 7 8 8 $ python modelviz.py <app_label> > <filename>.dot 9 $ python modelviz.py [-h] [-d] <app_label> ... <app_label> > <filename>.dot 10 $ dot <filename>.dot -Tpng -o <filename>.png 11 12 options: 13 -h, --help 14 show this help message and exit. 15 16 -d, --disable_fields 17 don't show the class member fields. 9 18 """ 10 11 __version__ = "0.6" 19 __version__ = "0.7" 12 20 __svnid__ = "$Id$" 13 21 __license__ = "Python" … … 16 24 "Stefano J. Attardi <http://attardi.org/>", 17 25 "limodou <http://www.donews.net/limodou/>", 18 "Carlo C8E Miron" 26 "Carlo C8E Miron", 27 "Andre Campos <cahenan@gmail.com>", 19 28 ] 20 29 30 import getopt, sys 31 32 from django.core.management import setup_environ 33 34 try: 35 import settings 36 except ImportError: 37 pass 38 else: 39 setup_environ(settings) 40 41 from django.template import Template, Context 21 42 from django.db import models 22 43 from django.db.models import get_models 23 44 from django.db.models.fields.related import \ 24 45 ForeignKey, OneToOneField, ManyToManyField 25 from django.db.models.fields.generic import GenericRelation26 from django.template import Template, Context27 46 28 dot_template = """ 29 digraph {{ name }} { 47 try: 48 from django.db.models.fields.generic import GenericRelation 49 except ImportError: 50 from django.contrib.contenttypes.generic import GenericRelation 51 52 head_template = """ 53 digraph name { 30 54 fontname = "Helvetica" 31 55 fontsize = 8 … … 41 65 ] 42 66 67 """ 68 69 body_template = """ 43 70 {% for model in models %} 44 {{ model.name }} [label=< 71 {% for relation in model.relations %} 72 {{ relation.target }} [label=< 73 <TABLE BGCOLOR="palegoldenrod" BORDER="0" CELLBORDER="0" CELLSPACING="0"> 74 <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="olivedrab4" 75 ><FONT FACE="Helvetica Bold" COLOR="white" 76 >{{ relation.target }}</FONT></TD></TR> 77 </TABLE> 78 >] 79 {{ model.name }} -> {{ relation.target }} 80 [label="{{ relation.name }}"] {{ relation.arrows }}; 81 {% endfor %} 82 {% endfor %} 83 84 {% for model in models %} 85 {{ model.name }} [label=< 45 86 <TABLE BGCOLOR="palegoldenrod" BORDER="0" CELLBORDER="0" CELLSPACING="0"> 46 87 <TR><TD COLSPAN="2" CELLPADDING="4" ALIGN="CENTER" BGCOLOR="olivedrab4" 47 88 ><FONT FACE="Helvetica Bold" COLOR="white" 48 89 >{{ 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 %} 90 91 {% if not disable_fields %} 92 {% for field in model.fields %} 93 <TR><TD ALIGN="LEFT" BORDER="0" 94 ><FONT FACE="Helvetica Bold">{{ field.name }}</FONT 95 ></TD> 96 <TD ALIGN="LEFT">{{ field.type }}</TD></TR> 97 {% endfor %} 98 {% endif %} 55 99 </TABLE> 56 100 >] 57 58 {% for relation in model.relations %}59 {{ model.name }} -> {{ relation.target }}60 [label="{{ relation.type }}"] {{ relation.arrows }};61 101 {% endfor %} 62 {% endfor %} 102 """ 103 104 tail_template = """ 63 105 } 64 106 """ 65 107 66 def generate_dot(app_label): 67 app = models.get_app(app_label) 68 graph = Context({ 69 'name': '"%s"' % app.__name__, 70 'models': [] 71 }) 108 def generate_dot(app_labels, **kwargs): 109 disable_fields = kwargs.get('disable_fields', False) 72 110 73 for appmodel in get_models(app): 74 model = { 75 'name': appmodel.__name__, 76 'fields': [], 77 'relations': [] 78 } 111 dot = head_template 79 112 80 # model attributes 81 def add_attributes(): 82 model['fields'].append({ 83 'name': field.name, 84 'type': type(field).__name__ 85 }) 113 for app_label in app_labels: 114 app = models.get_app(app_label) 115 graph = Context({ 116 'name': '"%s"' % app.__name__, 117 'disable_fields': disable_fields, 118 'models': [] 119 }) 86 120 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()121 for appmodel in get_models(app): 122 model = { 123 'name': appmodel.__name__, 124 'fields': [], 125 'relations': [] 126 } 93 127 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) 128 # model attributes 129 def add_attributes(): 130 model['fields'].append({ 131 'name': field.name, 132 'type': type(field).__name__ 133 }) 103 134 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]") 135 for field in appmodel._meta.fields: 136 add_attributes() 109 137 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) 138 if appmodel._meta.many_to_many: 139 for field in appmodel._meta.many_to_many: 140 add_attributes() 141 142 # relations 143 def add_relation(extras=""): 144 _rel = { 145 'target': field.rel.to.__name__, 146 'type': type(field).__name__, 147 'name': field.name, 148 'arrows': extras 149 } 150 if _rel not in model['relations']: 151 model['relations'].append(_rel) 152 153 for field in appmodel._meta.fields: 154 if isinstance(field, ForeignKey): 155 add_relation() 156 elif isinstance(field, OneToOneField): 157 add_relation("[arrowhead=none arrowtail=none]") 158 159 if appmodel._meta.many_to_many: 160 for field in appmodel._meta.many_to_many: 161 if isinstance(field, ManyToManyField): 162 add_relation("[arrowhead=normal arrowtail=normal]") 163 elif isinstance(field, GenericRelation): 164 add_relation( 165 '[style="dotted"] [arrowhead=normal arrowtail=normal]') 166 graph['models'].append(model) 167 168 t = Template(body_template) 169 dot += '\n' + t.render(graph) 170 171 dot += '\n' + tail_template 172 173 return dot 174 175 def main(): 176 try: 177 opts, args = getopt.getopt(sys.argv[1:], "hd", 178 ["help", "disable_fields"]) 179 except getopt.GetoptError, error: 180 print __doc__ 181 sys.exit(error) 182 else: 183 if not args: 184 print __doc__ 185 sys.exit() 186 187 kwargs = {} 188 for opt, arg in opts: 189 if opt in ("-h", "--help"): 190 print __doc__ 191 sys.exit() 192 if opt in ("-d", "--disable_fields"): 193 kwargs['disable_fields'] = True 194 print generate_dot(args, **kwargs) 121 195 122 196 if __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__ 197 main()