代码改变世界

【原创分享】django-m2doc, 自动根据project下的所有models生成数据表结构文档.

2011-03-18 12:00  码农.KEN  阅读(1976)  评论(2编辑  收藏  举报

背景

  一般在开发项目之前都会先绘出ER图等,但在使用Django做项目时都是希望快速搭建,所以都在大脑中构思好草图之后,直接开始coding建模,其实个人认为阅读django的models就已经能非常清晰的了解到对象关系等了,但毕竟有时候你的项目是需要给别人看的(如:客户),所以还是需要有规范的文档. 此时,我们需要一个工具能根据已coding好的Models自动生成Document.

  对于上述需求,我认为应该是很常见的.但GOOGLE一圈确实没有发现类似的工具, 于是便自己动手实现,顺便起了个名字就叫django-m2doc吧.

预览

  

实现

  能够轻松实现该功能,得益于python这门简易强大的动态语言特性,使我们能够很容易得到任意对象的属性.

  其中主要用到两点:

    1.inspect

    2.dynamic import

  完整代码:

#coding:utf-8

import sys, os
import inspect
from django.conf import settings
from django.db import models
from django.template import Context, Template

template = '''
    <html>
        <head>
            <title>Data table schema document</title>
            <style type="text/css">
                .loopeven {background:#f1f1f1;}
                .loopodd {}
            </style>
        </head>
        <body>
            {%for model,fields in models%}
            <div style="clear:both; margin-top:40px; display:inline;">
                <table border="0" width="100%">
                    <tbody>
                        <tr><td colspan="4" style="border:1px solid #000;"><b>Model Name: {{model|safe}}<b></td></tr>
                        <tr style="background:#000; color:#fff;"><th width="15%">列名</th><th width="15%">简称</th><th width="15%">列类型</th><th>描述</th><tr>
                        {%for field in fields%}
                        <tr style="background:#{%cycle 'f1f1f1' 'ffffff'%}">
                            <td>{{field.name}}</td>
                            <td>{{field.verbose_name}}</td>
                            <td>{{field.class_name}}{%if field.related_name%}({{field.related_name}}){%endif%}</td>
                            <td>{{field.help_text}}</td>
                        <tr>
                        {%endfor%}
                    </tbody>
                </table>
            </div>
            {%endfor%}
            <div style="margin-top:50px; padding:10px; width:100%;
            text-align:center;">this document generated by the <a href="http://ken-zhang.cnblogs.com"> django-m2doc</a></div>
        </body>
    </html>
'''

def get_propertys(cls):
    fields = []
    for f in cls._meta._fields():
        setattr(f, 'class_name', f.__class__.__name__)
        if hasattr(f, 'related'):
            setattr(f, 'related_name', f.related.parent_model.__name__)
        fields.append(f)
    return fields

def main():
    mod_list = []
    model_list = []
    for app in settings.INSTALLED_APPS:
        mod_list.append('%s.%s' % (app, 'models'))
    modules = map(__import__, mod_list)
    for s_model in mod_list:
        for member in inspect.getmembers(sys.modules[s_model], predicate=inspect.isclass):
            name,obj=member
            module_name = inspect.getmodule(obj).__name__
            print module_name
            if module_name == s_model and hasattr(obj, '_meta') and not module_name.startswith('south.'):
                model_list.append((obj.__name__, get_propertys(obj)))
    if model_list:
        t = Template(template)
        c = Context({'models':model_list})
        html = t.render(c)
        html_file = open('models_doc.html', 'w+')
        html_file.write(html)
        html_file.close()

if __name__ == '__main__':
    main()

说明

  该程序将自动查找settings.INSTALLED_APPS中已定义的app下的models并生成文档,将保存在path/to/project/models_doc.html