1
0
mirror of https://github.com/django/django.git synced 2025-07-03 01:09:12 +00:00

magic-removal: Refactored get_installed_models and get_installed_model_modules to get_apps, get_app, get_models and get_model

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2106 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-01-23 02:29:34 +00:00
parent 17ece1adb8
commit 25e1e1392f
7 changed files with 166 additions and 178 deletions

View File

@ -1,4 +1,5 @@
from django import template from django import template
from django.db.models import get_models
register = template.Library() register = template.Library()
@ -12,13 +13,18 @@ class AdminApplistNode(template.Node):
app_list = [] app_list = []
user = context['user'] user = context['user']
for app in models.get_installed_model_modules(): for app in models.get_apps():
app_label = app.__name__.split('.')[-2] # TODO: Abstract this logic # Determine the app_label.
app_models = get_models(app)
if not app_models:
continue
app_label = app_models[0]._meta.app_label
has_module_perms = user.has_module_perms(app_label) has_module_perms = user.has_module_perms(app_label)
if has_module_perms: if has_module_perms:
model_list = [] model_list = []
for m in app._MODELS: for m in app_models:
if m._meta.admin: if m._meta.admin:
perms = { perms = {
'add': user.has_perm("%s.%s" % (app_label, m._meta.get_add_permission())), 'add': user.has_perm("%s.%s" % (app_label, m._meta.get_add_permission())),

View File

@ -137,10 +137,7 @@ def model_index(request):
if not utils.docutils_is_available: if not utils.docutils_is_available:
return missing_docutils_page(request) return missing_docutils_page(request)
m_list = [] m_list = [m._meta for m in models.get_models()]
for app in models.get_installed_model_modules():
for model in app._MODELS:
m_list.append(model._meta)
return render_to_response('admin_doc/model_index', {'models': m_list}, context_instance=RequestContext(request)) return render_to_response('admin_doc/model_index', {'models': m_list}, context_instance=RequestContext(request))
model_index = staff_member_required(model_index) model_index = staff_member_required(model_index)

View File

@ -41,14 +41,6 @@ use_raw_id_admin = lambda field: isinstance(field.rel, (models.ManyToOne, models
class IncorrectLookupParameters(Exception): class IncorrectLookupParameters(Exception):
pass pass
def get_model(app_label, model_name):
for module in models.get_installed_models():
if module.__name__.split('.')[-2] == app_label: # TODO: Refactor this logic.
for model in getattr(module, '_MODELS', ()):
if model._meta.object_name.lower() == model_name:
return model
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
def get_javascript_imports(opts, auto_populated_fields, field_sets): def get_javascript_imports(opts, auto_populated_fields, field_sets):
# Put in any necessary JavaScript imports. # Put in any necessary JavaScript imports.
js = ['js/core.js', 'js/admin/RelatedObjectLookups.js'] js = ['js/core.js', 'js/admin/RelatedObjectLookups.js']
@ -192,7 +184,9 @@ def index(request):
index = staff_member_required(index) index = staff_member_required(index)
def add_stage(request, app_label, model_name, show_delete=False, form_url='', post_url='../', post_url_continue='../%s/', object_id_override=None): def add_stage(request, app_label, model_name, show_delete=False, form_url='', post_url='../', post_url_continue='../%s/', object_id_override=None):
model = get_model(app_label, model_name) model = models.get_model(app_label, model_name)
if model is None:
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
opts = model._meta opts = model._meta
if not request.user.has_perm(app_label + '.' + opts.get_add_permission()): if not request.user.has_perm(app_label + '.' + opts.get_add_permission()):
@ -255,7 +249,9 @@ def add_stage(request, app_label, model_name, show_delete=False, form_url='', po
add_stage = staff_member_required(add_stage) add_stage = staff_member_required(add_stage)
def change_stage(request, app_label, model_name, object_id): def change_stage(request, app_label, model_name, object_id):
model = get_model(app_label, model_name) model = models.get_model(app_label, model_name)
if model is None:
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
opts = model._meta opts = model._meta
if not request.user.has_perm(app_label + '.' + opts.get_change_permission()): if not request.user.has_perm(app_label + '.' + opts.get_change_permission()):
@ -436,7 +432,9 @@ def _get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current
def delete_stage(request, app_label, model_name, object_id): def delete_stage(request, app_label, model_name, object_id):
import sets import sets
model = get_model(app_label, model_name) model = models.get_model(app_label, model_name)
if model is None:
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
opts = model._meta opts = model._meta
if not request.user.has_perm(app_label + '.' + opts.get_delete_permission()): if not request.user.has_perm(app_label + '.' + opts.get_delete_permission()):
raise PermissionDenied raise PermissionDenied
@ -466,7 +464,9 @@ def delete_stage(request, app_label, model_name, object_id):
delete_stage = staff_member_required(delete_stage) delete_stage = staff_member_required(delete_stage)
def history(request, app_label, model_name, object_id): def history(request, app_label, model_name, object_id):
model = get_model(app_label, model_name) model = models.get_model(app_label, model_name)
if model is None:
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
action_list = LogEntry.objects.get_list(object_id__exact=object_id, content_type__id__exact=model._meta.get_content_type_id(), action_list = LogEntry.objects.get_list(object_id__exact=object_id, content_type__id__exact=model._meta.get_content_type_id(),
order_by=("action_time",), select_related=True) order_by=("action_time",), select_related=True)
# If no history was found, see whether this object even exists. # If no history was found, see whether this object even exists.
@ -651,7 +651,9 @@ class ChangeList(object):
self.lookup_params = lookup_params self.lookup_params = lookup_params
def change_list(request, app_label, model_name): def change_list(request, app_label, model_name):
model = get_model(app_label, model_name) model = models.get_model(app_label, model_name)
if model is None:
raise Http404, "App %r, model %r, not found" % (app_label, model_name)
if not request.user.has_perm(app_label + '.' + model._meta.get_change_permission()): if not request.user.has_perm(app_label + '.' + model._meta.get_change_permission()):
raise PermissionDenied raise PermissionDenied
try: try:

View File

@ -767,101 +767,99 @@ def get_validation_errors(outfile):
"Validates all installed models. Writes errors, if any, to outfile. Returns number of errors." "Validates all installed models. Writes errors, if any, to outfile. Returns number of errors."
from django.db import models from django.db import models
e = ModelErrorCollection(outfile) e = ModelErrorCollection(outfile)
module_list = models.get_installed_model_modules() for cls in models.get_models():
for module in module_list: opts = cls._meta
for cls in module._MODELS:
opts = cls._meta
# Do field-specific validation. # Do field-specific validation.
for f in opts.fields: for f in opts.fields:
# Check for deprecated args # Check for deprecated args
dep_args = getattr(f, 'deprecated_args', None) dep_args = getattr(f, 'deprecated_args', None)
if dep_args: if dep_args:
e.add(opts, "'%s' field: Initialised with deprecated args:%s" % (f.name, ",".join(dep_args))) e.add(opts, "'%s' field: Initialised with deprecated args:%s" % (f.name, ",".join(dep_args)))
if isinstance(f, models.CharField) and f.maxlength in (None, 0): if isinstance(f, models.CharField) and f.maxlength in (None, 0):
e.add(opts, '"%s" field: CharFields require a "maxlength" attribute.' % f.name) e.add(opts, '"%s" field: CharFields require a "maxlength" attribute.' % f.name)
if isinstance(f, models.FloatField): if isinstance(f, models.FloatField):
if f.decimal_places is None: if f.decimal_places is None:
e.add(opts, '"%s" field: FloatFields require a "decimal_places" attribute.' % f.name) e.add(opts, '"%s" field: FloatFields require a "decimal_places" attribute.' % f.name)
if f.max_digits is None: if f.max_digits is None:
e.add(opts, '"%s" field: FloatFields require a "max_digits" attribute.' % f.name) e.add(opts, '"%s" field: FloatFields require a "max_digits" attribute.' % f.name)
if isinstance(f, models.FileField) and not f.upload_to: if isinstance(f, models.FileField) and not f.upload_to:
e.add(opts, '"%s" field: FileFields require an "upload_to" attribute.' % f.name) e.add(opts, '"%s" field: FileFields require an "upload_to" attribute.' % f.name)
if isinstance(f, models.ImageField): if isinstance(f, models.ImageField):
try: try:
from PIL import Image from PIL import Image
except ImportError: except ImportError:
e.add(opts, '"%s" field: To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name) e.add(opts, '"%s" field: To use ImageFields, you need to install the Python Imaging Library. Get it at http://www.pythonware.com/products/pil/ .' % f.name)
if f.prepopulate_from is not None and type(f.prepopulate_from) not in (list, tuple): if f.prepopulate_from is not None and type(f.prepopulate_from) not in (list, tuple):
e.add(opts, '"%s" field: prepopulate_from should be a list or tuple.' % f.name) e.add(opts, '"%s" field: prepopulate_from should be a list or tuple.' % f.name)
if f.choices: if f.choices:
if not type(f.choices) in (tuple, list): if not type(f.choices) in (tuple, list):
e.add(opts, '"%s" field: "choices" should be either a tuple or list.' % f.name) e.add(opts, '"%s" field: "choices" should be either a tuple or list.' % f.name)
else:
for c in f.choices:
if not type(c) in (tuple, list) or len(c) != 2:
e.add(opts, '"%s" field: "choices" should be a sequence of two-tuples.' % f.name)
if f.db_index not in (None, True, False):
e.add(opts, '"%s" field: "db_index" should be either None, True or False.' % f.name)
# Check for multiple ManyToManyFields to the same object, and
# verify "singular" is set in that case.
for i, f in enumerate(opts.many_to_many):
for previous_f in opts.many_to_many[:i]:
if f.rel.to._meta == previous_f.rel.to._meta and f.rel.singular == previous_f.rel.singular:
e.add(opts, 'The "%s" field requires a "singular" parameter, because the %s model has more than one ManyToManyField to the same model (%s).' % (f.name, opts.object_name, previous_f.rel.to._meta.object_name))
# Check admin attribute.
if opts.admin is not None:
if not isinstance(opts.admin, models.AdminOptions):
e.add(opts, '"admin" attribute, if given, must be set to a models.AdminOptions() instance.')
else: else:
# list_display for c in f.choices:
if not isinstance(opts.admin.list_display, (list, tuple)): if not type(c) in (tuple, list) or len(c) != 2:
e.add(opts, '"admin.list_display", if given, must be set to a list or tuple.') e.add(opts, '"%s" field: "choices" should be a sequence of two-tuples.' % f.name)
else: if f.db_index not in (None, True, False):
for fn in opts.admin.list_display: e.add(opts, '"%s" field: "db_index" should be either None, True or False.' % f.name)
try:
f = opts.get_field(fn)
except models.FieldDoesNotExist:
if not hasattr(cls, fn) or not callable(getattr(cls, fn)):
e.add(opts, '"admin.list_display" refers to %r, which isn\'t a field or method.' % fn)
else:
if isinstance(f, models.ManyToManyField):
e.add(opts, '"admin.list_display" doesn\'t support ManyToManyFields (%r).' % fn)
# list_filter
if not isinstance(opts.admin.list_filter, (list, tuple)):
e.add(opts, '"admin.list_filter", if given, must be set to a list or tuple.')
else:
for fn in opts.admin.list_filter:
try:
f = opts.get_field(fn)
except models.FieldDoesNotExist:
e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn)
# Check ordering attribute. # Check for multiple ManyToManyFields to the same object, and
if opts.ordering: # verify "singular" is set in that case.
for field_name in opts.ordering: for i, f in enumerate(opts.many_to_many):
if field_name == '?': continue for previous_f in opts.many_to_many[:i]:
if field_name.startswith('-'): if f.rel.to._meta == previous_f.rel.to._meta and f.rel.singular == previous_f.rel.singular:
field_name = field_name[1:] e.add(opts, 'The "%s" field requires a "singular" parameter, because the %s model has more than one ManyToManyField to the same model (%s).' % (f.name, opts.object_name, previous_f.rel.to._meta.object_name))
if opts.order_with_respect_to and field_name == '_order':
continue
try:
opts.get_field(field_name, many_to_many=False)
except models.FieldDoesNotExist:
e.add(opts, '"ordering" refers to "%s", a field that doesn\'t exist.' % field_name)
# Check unique_together. # Check admin attribute.
for ut in opts.unique_together: if opts.admin is not None:
for field_name in ut: if not isinstance(opts.admin, models.AdminOptions):
try: e.add(opts, '"admin" attribute, if given, must be set to a models.AdminOptions() instance.')
f = opts.get_field(field_name, many_to_many=True) else:
except models.FieldDoesNotExist: # list_display
e.add(opts, '"unique_together" refers to %s, a field that doesn\'t exist. Check your syntax.' % field_name) if not isinstance(opts.admin.list_display, (list, tuple)):
else: e.add(opts, '"admin.list_display", if given, must be set to a list or tuple.')
if isinstance(f.rel, models.ManyToMany): else:
e.add(opts, '"unique_together" refers to %s. ManyToManyFields are not supported in unique_together.' % f.name) for fn in opts.admin.list_display:
try:
f = opts.get_field(fn)
except models.FieldDoesNotExist:
if not hasattr(cls, fn) or not callable(getattr(cls, fn)):
e.add(opts, '"admin.list_display" refers to %r, which isn\'t a field or method.' % fn)
else:
if isinstance(f, models.ManyToManyField):
e.add(opts, '"admin.list_display" doesn\'t support ManyToManyFields (%r).' % fn)
# list_filter
if not isinstance(opts.admin.list_filter, (list, tuple)):
e.add(opts, '"admin.list_filter", if given, must be set to a list or tuple.')
else:
for fn in opts.admin.list_filter:
try:
f = opts.get_field(fn)
except models.FieldDoesNotExist:
e.add(opts, '"admin.list_filter" refers to %r, which isn\'t a field.' % fn)
# Check ordering attribute.
if opts.ordering:
for field_name in opts.ordering:
if field_name == '?': continue
if field_name.startswith('-'):
field_name = field_name[1:]
if opts.order_with_respect_to and field_name == '_order':
continue
try:
opts.get_field(field_name, many_to_many=False)
except models.FieldDoesNotExist:
e.add(opts, '"ordering" refers to "%s", a field that doesn\'t exist.' % field_name)
# Check unique_together.
for ut in opts.unique_together:
for field_name in ut:
try:
f = opts.get_field(field_name, many_to_many=True)
except models.FieldDoesNotExist:
e.add(opts, '"unique_together" refers to %s, a field that doesn\'t exist. Check your syntax.' % field_name)
else:
if isinstance(f.rel, models.ManyToMany):
e.add(opts, '"unique_together" refers to %s. ManyToManyFields are not supported in unique_together.' % f.name)
return len(e.errors) return len(e.errors)

View File

@ -2,7 +2,7 @@ from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
from django.core import validators from django.core import validators
from django.db import backend, connection from django.db import backend, connection
from django.db.models.loading import get_installed_models, get_installed_model_modules from django.db.models.loading import *
from django.db.models.query import Q from django.db.models.query import Q
from django.db.models.manager import Manager from django.db.models.manager import Manager
from django.db.models.base import Model, AdminOptions from django.db.models.base import Model, AdminOptions
@ -16,27 +16,6 @@ from django.utils.text import capfirst
# Admin stages. # Admin stages.
ADD, CHANGE, BOTH = 1, 2, 3 ADD, CHANGE, BOTH = 1, 2, 3
def get_models(app):
models = []
get_models_helper(app, models)
return models
def get_models_helper(mod, seen_models):
if hasattr(mod, '_MODELS'):
seen_models.extend(mod._MODELS)
if hasattr(mod, '__all__'):
for name in mod.__all__:
sub_mod = __import__("%s.%s" % (mod.__name__, name), '', '', [''])
get_models_helper(sub_mod, seen_models)
def get_app(app_label):
for app_name in settings.INSTALLED_APPS:
comps = app_name.split('.')
if app_label == comps[-1]:
app_models = __import__('%s.models' % app_name, '', '', [''])
return app_models
raise ImproperlyConfigured, "App with label %s could not be found" % app_label
class LazyDate: class LazyDate:
""" """
Use in limit_choices_to to compare the field to dates calculated at run time Use in limit_choices_to to compare the field to dates calculated at run time

View File

@ -1,40 +1,50 @@
from django.conf import settings "Utilities for loading models and the modules that contain them."
_installed_models_cache = None
def get_installed_models(): from django.conf import settings
"""
Returns a list of installed "models" packages, such as foo.models, __all__ = ('get_apps', 'get_app', 'get_models', 'get_model')
ellington.news.models, etc. This does NOT include django.models.
""" _app_list = None # Cache of installed apps.
global _installed_models_cache
if _installed_models_cache is not None: def get_apps():
return _installed_models_cache "Returns a list of all installed modules that contain models."
_installed_models_cache = [] global _app_list
for a in settings.INSTALLED_APPS: if _app_list is not None:
return _app_list
_app_list = []
for app_name in settings.INSTALLED_APPS:
try: try:
_installed_models_cache.append(__import__(a + '.models', '', '', [''])) _app_list.append(__import__(app_name + '.models', '', '', ['']))
except ImportError, e: except ImportError, e:
pass pass
return _installed_models_cache return _app_list
_installed_modules_cache = None def get_app(app_label):
"Returns the module containing the models for the given app_label."
for app_name in settings.INSTALLED_APPS:
if app_label == app_name.split('.')[-1]:
return __import__('%s.models' % app_name, '', '', [''])
raise ImproperlyConfigured, "App with label %s could not be found" % app_label
def add_model_module(mod, modules): def get_models(app_mod=None):
if hasattr(mod, '_MODELS'):
modules.append(mod)
for name in getattr(mod, '__all__', []):
submod = __import__("%s.%s" % (mod.__name__, name), '', '', [''])
add_model_module(submod, modules)
def get_installed_model_modules():
""" """
Returns a list of installed models, such as django.models.core, Given a module containing models, returns a list of the models. Otherwise
ellington.news.models.news, foo.models.bar, etc. returns a list of all installed models.
""" """
global _installed_modules_cache if app_mod:
if _installed_modules_cache is not None: return getattr(app_mod, '_MODELS', ())
return _installed_modules_cache else:
_installed_modules_cache = [] model_list = []
for mod in get_installed_models(): for app_mod in get_apps():
add_model_module(mod, _installed_modules_cache) model_list.extend(getattr(app_mod, '_MODELS', ()))
return _installed_modules_cache return model_list
def get_model(app_label, model_name):
"""
Returns the model matching the given app_label and case-insensitive model_name.
Returns None if no model is found.
"""
for app_mod in get_apps():
for model in get_models(app_mod):
if model._meta.object_name.lower() == model_name:
return model

View File

@ -1,7 +1,7 @@
from django.db.models.related import RelatedObject from django.db.models.related import RelatedObject
from django.db.models.fields.related import ManyToMany from django.db.models.fields.related import ManyToMany
from django.db.models.fields import AutoField from django.db.models.fields import AutoField
from django.db.models.loading import get_installed_model_modules from django.db.models.loading import get_models
from django.db.models.query import orderlist2sql from django.db.models.query import orderlist2sql
from django.db.models.exceptions import FieldDoesNotExist from django.db.models.exceptions import FieldDoesNotExist
from bisect import bisect from bisect import bisect
@ -127,13 +127,11 @@ class Options:
try: # Try the cache first. try: # Try the cache first.
return self._all_related_objects return self._all_related_objects
except AttributeError: except AttributeError:
module_list = get_installed_model_modules()
rel_objs = [] rel_objs = []
for mod in module_list: for klass in get_models():
for klass in mod._MODELS: for f in klass._meta.fields:
for f in klass._meta.fields: if f.rel and self == f.rel.to._meta:
if f.rel and self == f.rel.to._meta: rel_objs.append(RelatedObject(self, klass, f))
rel_objs.append(RelatedObject(self, klass, f))
self._all_related_objects = rel_objs self._all_related_objects = rel_objs
return rel_objs return rel_objs
@ -163,13 +161,11 @@ class Options:
try: # Try the cache first. try: # Try the cache first.
return self._all_related_many_to_many_objects return self._all_related_many_to_many_objects
except AttributeError: except AttributeError:
module_list = get_installed_model_modules()
rel_objs = [] rel_objs = []
for mod in module_list: for klass in get_models():
for klass in mod._MODELS: for f in klass._meta.many_to_many:
for f in klass._meta.many_to_many: if f.rel and self == f.rel.to._meta:
if f.rel and self == f.rel.to._meta: rel_objs.append(RelatedObject(self, klass, f))
rel_objs.append(RelatedObject(self, klass, f))
self._all_related_many_to_many_objects = rel_objs self._all_related_many_to_many_objects = rel_objs
return rel_objs return rel_objs