Ticket #3591: custom-app-labels.diff

File custom-app-labels.diff, 20.6 KB (added by jkocherhans, 9 years ago)

A couple of internal tests are still broken, but admin, manage.py, etc. work

  • django/test/client.py

     
    167167        if response.cookies:
    168168            self.cookies.update(response.cookies)
    169169
    170         if 'django.contrib.sessions' in settings.INSTALLED_APPS:
     170        if 'django.contrib.sessions' in [app.path for app in settings.INSTALLED_APPS]:
    171171            from django.contrib.sessions.middleware import SessionWrapper
    172172            cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
    173173            if cookie:
  • django/db/models/base.py

     
    88from django.db.models.options import Options, AdminOptions
    99from django.db import connection, backend, transaction
    1010from django.db.models import signals
    11 from django.db.models.loading import register_models, get_model
     11from django.db.models.loading import register_models, get_model, get_app_label
    1212from django.dispatch import dispatcher
    1313from django.utils.datastructures import SortedDict
    1414from django.utils.functional import curry
     
    4242        if getattr(new_class._meta, 'app_label', None) is None:
    4343            # Figure out the app_label by looking one level up.
    4444            # For 'django.contrib.sites.models', this would be 'sites'.
    45             new_class._meta.app_label = model_module.__name__.split('.')[-2]
     45            new_class._meta.app_label = get_app_label(new_class)
     46            #new_class._meta.app_label = model_module.__name__.split('.')[-2]
    4647
    4748        # Bail out early if we have already created this class.
    4849        m = get_model(new_class._meta.app_label, name, False)
  • django/db/models/options.py

     
    3636
    3737    def contribute_to_class(self, cls, name):
    3838        cls._meta = self
    39         self.installed = re.sub('\.models$', '', cls.__module__) in settings.INSTALLED_APPS
     39        self.installed = re.sub('\.models$', '', cls.__module__) in [app.path for app in settings.INSTALLED_APPS]
    4040        # First, construct the default values for these options.
    4141        self.object_name = cls.__name__
    4242        self.module_name = self.object_name.lower()
  • django/db/models/loading.py

     
    11"Utilities for loading models and the modules that contain them."
    22
    3 from django.conf import settings
     3from django.conf import settings, directives
    44from django.core.exceptions import ImproperlyConfigured
    55import sys
    66import os
     
    2424    global _loaded
    2525    if not _loaded:
    2626        _loaded = True
    27         for app_name in settings.INSTALLED_APPS:
     27        for app in settings.INSTALLED_APPS:
    2828            try:
    29                 load_app(app_name)
     29                load_app(app.path)
    3030            except Exception, e:
    3131                # Problem importing the app
    32                 _app_errors[app_name] = e
     32                _app_errors[app.path] = e
    3333    return _app_list
    3434
    3535def get_app(app_label, emptyOK=False):
    3636    "Returns the module containing the models for the given app_label. If the app has no models in it and 'emptyOK' is True, returns None."
    3737    get_apps() # Run get_apps() to populate the _app_list cache. Slightly hackish.
    38     for app_name in settings.INSTALLED_APPS:
    39         if app_label == app_name.split('.')[-1]:
    40             mod = load_app(app_name)
     38    for app in settings.INSTALLED_APPS:
     39        if app_label == app.app_label:
     40            mod = load_app(app.path)
    4141            if mod is None:
    4242                if emptyOK:
    4343                    return None
     
    6161    get_apps() # Run get_apps() to populate the _app_list cache. Slightly hackish.
    6262    return _app_errors
    6363
    64 def get_models(app_mod=None):
     64def get_models(app=None):
    6565    """
    66     Given a module containing models, returns a list of the models. Otherwise
    67     returns a list of all installed models.
     66    Given a app config directive, returns a list of the models in that app.
     67    Otherwise returns a list of all installed models.
    6868    """
    6969    app_list = get_apps() # Run get_apps() to populate the _app_list cache. Slightly hackish.
    70     if app_mod:
    71         return _app_models.get(app_mod.__name__.split('.')[-2], {}).values()
     70    if app:
     71        if isinstance(app, str):
     72            print app
     73            app = app_for_label(app)
     74            print app
     75        return _app_models.get(app.app_label, {}).values()
    7276    else:
    7377        model_list = []
    74         for app_mod in app_list:
    75             model_list.extend(get_models(app_mod))
     78        for app in settings.INSTALLED_APPS:
     79            model_list.extend(get_models(app))
    7680        return model_list
    7781
    7882def get_model(app_label, model_name, seed_cache=True):
     
    114118            if os.path.splitext(fname1)[0] == os.path.splitext(fname2)[0]:
    115119                continue
    116120        model_dict[model_name] = model
     121
     122def get_app_label(model):
     123    model_module_path = model.__module__
     124    model_module_path_list = model_module_path.split('.')
     125    model_module_index = model_module_path_list.index('models')
     126    app_module_path_list = model_module_path_list[:model_module_index]
     127    app_module_path = '.'.join(app_module_path_list)   
     128    for app in settings.INSTALLED_APPS:
     129        if app_module_path == app.path:
     130            return app.app_label
     131    # app is most likely not installed, but give it an app label using the old method
     132    return model.__module__.split('.')[-2]
     133
     134def app_for_path(path):
     135    for app in settings.INSTALLED_APPS:
     136        if path == app.path:
     137            return app
     138    # app is most likely not installed, but give it an app label using the old method
     139    return directives.app(path.split('.')[-1])
     140
     141def app_for_label(app_label):
     142    for app in settings.INSTALLED_APPS:
     143        if app_label == app.app_label:
     144            return app
  • django/conf/__init__.py

     
    88
    99import os
    1010import time     # Needed for Windows
    11 from django.conf import global_settings
     11from django.conf import global_settings, directives
     12from django.utils.datastructures import SortedDict
    1213
    1314ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
    1415
     
    9495                setattr(self, setting, setting_value)
    9596
    9697        # Expand entries in INSTALLED_APPS like "django.contrib.*" to a list
    97         # of all those apps.
     98        # of all those apps. Also, convert strings into app directives.
    9899        new_installed_apps = []
    99100        for app in self.INSTALLED_APPS:
    100             if app.endswith('.*'):
    101                 appdir = os.path.dirname(__import__(app[:-2], {}, {}, ['']).__file__)
    102                 for d in os.listdir(appdir):
    103                     if d.isalpha() and os.path.isdir(os.path.join(appdir, d)):
    104                         new_installed_apps.append('%s.%s' % (app[:-2], d))
     101            if isinstance(app, str):
     102                if app.endswith('.*'):
     103                    appdir = os.path.dirname(__import__(app[:-2], {}, {}, ['']).__file__)
     104                    for d in os.listdir(appdir):
     105                        if d.isalpha() and os.path.isdir(os.path.join(appdir, d)):
     106                            new_app = directives.app('%s.%s' % (app[:-2], d))
     107                            new_installed_apps.append(new_app)
     108                else:
     109                    new_app = directives.app(app)
     110                    new_installed_apps.append(new_app)
    105111            else:
    106112                new_installed_apps.append(app)
    107113        self.INSTALLED_APPS = new_installed_apps
  • django/conf/directives.py

     
     1class app(object):
     2    """Configuration directive for specifying an app."""
     3    def __init__(self, path, app_label=None, verbose_name=None):
     4        self.path = path
     5        # if name isn't specified, get the last part of the python dotted path
     6        self.app_label = app_label or path.split('.')[-1]
     7        self.verbose_name = verbose_name or self.app_label
     8
     9class backend(object):
     10    """Configuration directive for specifying an authentication backend."""
     11    def __init__(self, path, name=None):
     12        self.path = path
     13        # if name isn't specified, get the last part of the python dotted path
     14        self.name = name or path.split('.')[-1]
  • django/core/management.py

     
    5656def _get_installed_models(table_list):
    5757    "Gets a set of all models that are installed, given a list of existing tables"
    5858    from django.db import models
    59     all_models = []
    60     for app in models.get_apps():
    61         for model in models.get_models(app):
    62             all_models.append(model)
     59    all_models = models.get_models()
    6360    return set([m for m in all_models if m._meta.db_table in table_list])
    6461
    6562def _get_table_list():
     
    363360
    364361def get_sql_initial_data(app):
    365362    "Returns a list of the initial INSERT SQL statements for the given app."
    366     from django.db.models import get_models
     363    from django.db import models
    367364    output = []
    368365
    369     app_models = get_models(app)
    370     app_dir = os.path.normpath(os.path.join(os.path.dirname(app.__file__), 'sql'))
     366    app_models = models.get_models(app)
     367    app_module = models.get_app(app.app_label)
     368    app_dir = os.path.normpath(os.path.join(os.path.dirname(app_module.__file__), 'sql'))
    371369
    372370    for model in app_models:
    373371        output.extend(get_sql_initial_data_for_model(model))
     
    450448
    451449    # Import the 'management' module within each installed app, to register
    452450    # dispatcher events.
    453     for app_name in settings.INSTALLED_APPS:
     451    for app in settings.INSTALLED_APPS:
    454452        try:
    455             __import__(app_name + '.management', {}, {}, [''])
     453            __import__(app.path + '.management', {}, {}, [''])
    456454        except ImportError:
    457455            pass
    458456
     
    469467    created_models = set()
    470468    pending_references = {}
    471469
    472     for app in models.get_apps():
    473         app_name = app.__name__.split('.')[-2]
     470    for app in settings.INSTALLED_APPS:
     471        app_name = app.path
    474472        model_list = models.get_models(app)
    475473        for model in model_list:
    476474            # Create the model's database table, if it doesn't already exist.
     
    503501
    504502    # Send the post_syncdb signal, so individual apps can do whatever they need
    505503    # to do at this point.
    506     for app in models.get_apps():
    507         app_name = app.__name__.split('.')[-2]
     504    for app in settings.INSTALLED_APPS:
     505        app_name = app.path
     506        app_module = models.get_app(app.app_label)
    508507        if verbosity >= 2:
    509508            print "Running post-sync handlers for application", app_name
    510         dispatcher.send(signal=signals.post_syncdb, sender=app,
     509        dispatcher.send(signal=signals.post_syncdb, sender=app_module,
    511510            app=app, created_models=created_models,
    512511            verbosity=verbosity, interactive=interactive)
    513512
     
    530529                        transaction.commit_unless_managed()
    531530
    532531    # Install SQL indicies for all newly created models
    533     for app in models.get_apps():
    534         app_name = app.__name__.split('.')[-2]
     532    for app in settings.INSTALLED_APPS:
     533        app_name = app.path
    535534        for model in models.get_models(app):
    536535            if model in created_models:
    537536                index_sql = get_sql_indexes_for_model(model)
     
    14021401        action_mapping[action](args[1:])
    14031402    else:
    14041403        from django.db import models
     1404        from django.conf import settings
    14051405        validate(silent_success=True)
    14061406        try:
    1407             mod_list = [models.get_app(app_label) for app_label in args[1:]]
     1407            app_list = [app for app in settings.INSTALLED_APPS if app.app_label in args[1:]]
    14081408        except ImportError, e:
    14091409            sys.stderr.write(style.ERROR("Error: %s. Are you sure your INSTALLED_APPS setting is correct?\n" % e))
    14101410            sys.exit(1)
    1411         if not mod_list:
     1411        if not app_list:
    14121412            parser.print_usage_and_exit()
    14131413        if action not in NO_SQL_TRANSACTION:
    14141414            print style.SQL_KEYWORD("BEGIN;")
    1415         for mod in mod_list:
     1415        for app in app_list:
    14161416            if action == 'reset':
    1417                 output = action_mapping[action](mod, options.interactive)
     1417                output = action_mapping[action](app, options.interactive)
    14181418            else:
    1419                 output = action_mapping[action](mod)
     1419                output = action_mapping[action](app)
    14201420            if output:
    14211421                print '\n'.join(output)
    14221422        if action not in NO_SQL_TRANSACTION:
  • django/templatetags/__init__.py

     
    11from django.conf import settings
    22
    3 for a in settings.INSTALLED_APPS:
     3for app in settings.INSTALLED_APPS:
    44    try:
    5         __path__.extend(__import__(a + '.templatetags', {}, {}, ['']).__path__)
     5        __path__.extend(__import__(app.path + '.templatetags', {}, {}, ['']).__path__)
    66    except ImportError:
    77        pass
  • django/views/i18n.py

     
    104104        packages = ['django.conf']
    105105    if type(packages) in (str, unicode):
    106106        packages = packages.split('+')
    107     packages = [p for p in packages if p == 'django.conf' or p in settings.INSTALLED_APPS]
     107    packages = [p for p in packages if p == 'django.conf' or p in [app.path for app in settings.INSTALLED_APPS]]
    108108    default_locale = to_locale(settings.LANGUAGE_CODE)
    109109    locale = to_locale(get_language())
    110110    t = {}
  • django/contrib/admin/templatetags/adminapplist.py

     
    11from django import template
    22from django.db.models import get_models
     3from django.conf import settings
    34
    45register = template.Library()
    56
     
    1314        app_list = []
    1415        user = context['user']
    1516
    16         for app in models.get_apps():
     17        for app in settings.INSTALLED_APPS:
    1718            # Determine the app_label.
    1819            app_models = get_models(app)
    1920            if not app_models:
    2021                continue
    21             app_label = app_models[0]._meta.app_label
     22            app_label = app.app_label
    2223
    2324            has_module_perms = user.has_module_perms(app_label)
    2425
     
    4950                    model_list = [x for key, x in decorated]
    5051
    5152                    app_list.append({
    52                         'name': app_label.title(),
     53                        'name': app.verbose_name.title(),
    5354                        'has_module_perms': has_module_perms,
    5455                        'models': model_list,
    5556                    })
  • django/utils/translation/trans_real.py

     
    161161        if projectpath and os.path.isdir(projectpath):
    162162            res = _merge(projectpath)
    163163
    164         for appname in settings.INSTALLED_APPS:
     164        for app in settings.INSTALLED_APPS:
     165            appname = app.path
    165166            p = appname.rfind('.')
    166167            if p >= 0:
    167                 app = getattr(__import__(appname[:p], {}, {}, [appname[p+1:]]), appname[p+1:])
     168                app_module = getattr(__import__(appname[:p], {}, {}, [appname[p+1:]]), appname[p+1:])
    168169            else:
    169                 app = __import__(appname, {}, {}, [])
     170                app_module = __import__(appname, {}, {}, [])
    170171
    171             apppath = os.path.join(os.path.dirname(app.__file__), 'locale')
     172            apppath = os.path.join(os.path.dirname(app_module.__file__), 'locale')
    172173
    173174            if os.path.isdir(apppath):
    174175                res = _merge(apppath)
  • django/template/loaders/app_directories.py

     
    88# At compile time, cache the directories to search.
    99app_template_dirs = []
    1010for app in settings.INSTALLED_APPS:
    11     i = app.rfind('.')
     11    i = app.path.rfind('.')
    1212    if i == -1:
    13         m, a = app, None
     13        m, a = app.path, None
    1414    else:
    15         m, a = app[:i], app[i+1:]
     15        m, a = app.path[:i], app.path[i+1:]
    1616    try:
    1717        if a is None:
    1818            mod = __import__(m, {}, {}, [])
    1919        else:
    2020            mod = getattr(__import__(m, {}, {}, [a]), a)
    2121    except ImportError, e:
    22         raise ImproperlyConfigured, 'ImportError %s: %s' % (app, e.args[0])
     22        raise ImproperlyConfigured, 'ImportError %s: %s' % (app.path, e.args[0])
    2323    template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
    2424    if os.path.isdir(template_dir):
    2525        app_template_dirs.append(template_dir)
  • django/template/loaders/eggs.py

     
    1818        pkg_name = 'templates/' + template_name
    1919        for app in settings.INSTALLED_APPS:
    2020            try:
    21                 return (resource_string(app, pkg_name), 'egg:%s:%s ' % (app, pkg_name))
     21                return (resource_string(app.path, pkg_name), 'egg:%s:%s ' % (app.path, pkg_name))
    2222            except:
    2323                pass
    2424    raise TemplateDoesNotExist, template_name
  • tests/runtests.py

     
    22
    33import os, sys, traceback
    44import unittest
     5from django.conf import directives
    56
    67MODEL_TESTS_DIR_NAME = 'modeltests'
    78REGRESSION_TESTS_DIR_NAME = 'regressiontests'
     
    1213REGRESSION_TEST_DIR = os.path.join(os.path.dirname(__file__), REGRESSION_TESTS_DIR_NAME)
    1314
    1415ALWAYS_INSTALLED_APPS = [
    15     'django.contrib.contenttypes',
    16     'django.contrib.auth',
    17     'django.contrib.sites',
    18     'django.contrib.flatpages',
    19     'django.contrib.redirects',
    20     'django.contrib.sessions',
    21     'django.contrib.comments',
    22     'django.contrib.admin',
     16    directives.app('django.contrib.contenttypes'),
     17    directives.app('django.contrib.auth'),
     18    directives.app('django.contrib.sites'),
     19    directives.app('django.contrib.flatpages'),
     20    directives.app('django.contrib.redirects'),
     21    directives.app('django.contrib.sessions'),
     22    directives.app('django.contrib.comments'),
     23    directives.app('django.contrib.admin'),
    2324]
    2425
    2526def get_test_models():
     
    4849
    4950    def runTest(self):
    5051        from django.core import management
    51         from django.db.models.loading import load_app
     52        from django.db.models.loading import load_app, app_for_path
    5253        from cStringIO import StringIO
    5354
    5455        try:
    5556            module = load_app(self.model_label)
     57            app = app_for_path(self.model_label)
    5658        except Exception, e:
     59            print self.model_label
     60            print e
    5761            self.fail('Unable to load invalid model module')
    5862
    5963        s = StringIO()
    60         count = management.get_validation_errors(s, module)
     64        count = management.get_validation_errors(s, app)
    6165        s.seek(0)
    6266        error_log = s.read()
    6367        actual = error_log.split('\n')
     
    108112            if not tests_to_run or model_name in tests_to_run:
    109113                if verbosity >= 1:
    110114                    print "Importing model %s" % model_name
     115                app = directives.app(model_label)
     116                settings.INSTALLED_APPS.append(app)
    111117                mod = load_app(model_label)
    112                 settings.INSTALLED_APPS.append(model_label)
    113118                test_models.append(mod)
    114119        except Exception, e:
    115120            sys.stderr.write("Error while importing %s:" % model_name + ''.join(traceback.format_exception(*sys.exc_info())[1:]))
Back to Top