Skip to content


Subversion checkout URL

You can clone with
Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

189 lines (167 sloc) 7.031 kB
from django.db.models import get_models
from data_structures import *
import sys
class DjangoModelInterface(object):
Abstracts Django specific parsing and editing.
def __init__(self):
raise "Nothing worth instantiating"
def load_aobjects(klass, include_prefixes=None, exclude_prefixes=None, include_django_contrib=False):
Loads selected models into AObjects
note: Must be run from within Django project.
note: In order for all relation edges to be shown,
all referenced models should be included.
@param include_prefixes: list of module prefixes from which to include models; eg, ['foo', 'bar']
if specified, other parameters are ignored
@param exclude_prefixes: list of module prefixes from which to exclude models; eg, ['foo', 'bar']
@param include_django_contrib: if True, includes models from django.contrib apps
@return: list of AObjects
print include_prefixes
print exclude_prefixes
models = klass._get_models(include_prefixes, exclude_prefixes, include_django_contrib)
Load models into internal data structures
1. First pass collects models as AObjects
2. Second pass sets fields, including ForeignKeys to AObjects
# All AObjects created from models
# model class object -> AObject
obj_dict = {}
klass._model_iterator(obj_dict, models, klass._first_pass)
klass._model_iterator(obj_dict, models, klass._second_pass)
return obj_dict.values()
def _get_models(klass, include_prefixes=None, exclude_prefixes=None, include_django_contrib=False):
Retrieves models based on the following rules:
1. All models from modules matching included prefixes are included.
Excluded and django contrib rules are ignored
2. All models from modules matching excluded prefixes are excluded.
3. Django contrib models are excluded unless include_django_contrib is True
DEBUG = False
include_prefixes = include_prefixes or []
exclude_prefixes = exclude_prefixes or []
models = []
for model in get_models():
if DEBUG: print "model", model.__module__, model.__name__
if include_prefixes:
for app in include_prefixes:
if DEBUG: print "include prefix: ", app
if model.__module__.startswith(app):
model_is_excluded = False
for app in exclude_prefixes:
if DEBUG: print "exclude prefix: ", app
if model.__module__.startswith(app):
model_is_excluded = True
if DEBUG: print "model is excluded = ", model_is_excluded
if model_is_excluded:
if include_django_contrib or not model.__module__.startswith('django.contrib'):
return models
def _first_pass(klass, obj_dict, model):
""" First pass collects models as AObjects """
# create AObject for model class
o = AObject(model.__name__)
obj_dict[model] = o
def _second_pass(klass, obj_dict, model):
""" Second pass sets fields, including ForeignKeys to AObjects """
# retrieve AObject for model class
o = obj_dict[model]
# iterate over model's fields to add AFields
for field in model._meta.fields:
f = AField(, field.get_internal_type())
if field.rel:
if in obj_dict:
def _model_iterator(klass, obj_dict, models, fn):
@param fn: function that takes 2 parameters:
klass (DjangoModelInterface instance)
model (class object)
for app in apps:
app = __import__(app)
# PD_SPECIFIC: use of ALL_MODELS, list of class names
for model in app.models.ALL_MODELS:
# retrieve class object for class name
#model = getattr(app.models, model)
fn(obj_dict, model)
for model in models:
fn(obj_dict, model)
def print_classes(klass, aobjects, filename=None):
Convenience function for printing create_classes
todo see python tokenizer and parser for manipulating code
lines = klass.create_classes(aobjects, filename)
if filename:
f = open(filename)
print "\n".join(lines)
def create_classes(klass, aobjects, filename=None):
@return: list of strings representing lines of code
lines = []
for aobject in aobjects:
lines.append("class %s(models.Model):" %
for field in aobject.fields:
p = []
if field.dest:
p.append("'%s'" %
if field.type == 'CharField':
lines.append(" %s = models.%s(%s)" % (,
", ".join(p)))
# ToDo: print __unicode__ and Make methods, also class docs (OG notes?)
# more default fields? what to express in omni graffle, visually v notes
return lines
####### DJANGO UTILTIES #######
def setup_django_environment():
""" Setup Django environment """
# Nearest ancestor directory with a '' file
settings_dir = _find_file_in_ancestors("")
from import setup_environ
import settings
def _find_file_in_ancestors(filename):
For each parent directory, check if 'filename' exists. If found, return
the path; otherwise raise RuntimeError.
import os
path = os.path.realpath(os.path.curdir)
while not filename in os.listdir(path):
#if filename in os.listdir(path):
# return path
newpath = os.path.split(path)[0]
if path == newpath:
raise RuntimeError("No file '%s' found in ancestor directories." % filename)
path = newpath
return path
Jump to Line
Something went wrong with that request. Please try again.