django-orchestra/orchestra/models/utils.py

51 lines
1.6 KiB
Python
Raw Normal View History

2014-05-08 16:59:35 +00:00
from django.conf import settings
2015-05-03 17:44:46 +00:00
from django.apps import apps
2015-05-01 17:23:22 +00:00
import importlib
2014-05-08 16:59:35 +00:00
def get_model(label, import_module=True):
app_label, model_name = label.split('.')
2015-05-03 17:44:46 +00:00
model = apps.get_model(app_label, model_name)
2014-05-08 16:59:35 +00:00
if model is None:
# Sometimes the models module is not yet imported
for app in settings.INSTALLED_APPS:
if app.endswith(app_label):
app_label = app
importlib.import_module('%s.%s' % (app_label, 'admin'))
2015-05-03 17:44:46 +00:00
return apps.get_model(*label.split('.'))
2014-05-08 16:59:35 +00:00
return model
def get_field_value(obj, field_name):
names = field_name.split('__')
rel = getattr(obj, names.pop(0))
for name in names:
try:
rel = getattr(rel, name)
except AttributeError:
2014-07-11 22:08:16 +00:00
# maybe is a query manager
2014-05-08 16:59:35 +00:00
rel = getattr(rel.get(), name)
return rel
2014-07-11 21:09:17 +00:00
def get_model_field_path(origin, target):
""" BFS search on model relaion fields """
2014-07-11 22:08:16 +00:00
queue = []
queue.append(([origin], []))
while queue:
model, path = queue.pop(0)
2014-07-11 21:09:17 +00:00
if len(model) > 4:
2014-09-17 10:32:29 +00:00
msg = "maximum recursion depth exceeded while looking for %s from %s"
raise RuntimeError(msg % (target, origin))
2014-07-11 21:09:17 +00:00
node = model[-1]
if node == target:
return path
for field in node._meta.fields:
if field.rel:
new_model = list(model)
new_model.append(field.rel.to)
new_path = list(path)
new_path.append(field.name)
2014-07-11 22:08:16 +00:00
queue.append((new_model, new_path))
raise LookupError("Path does not exists between '%s' and '%s' models" % (origin, target))