Changes between Initial Version and Version 1 of InstalledAppsRevision


Ignore:
Timestamp:
Mar 18, 2008, 6:14:22 PM (17 years ago)
Author:
Brantley
Comment:

Initial Import

Legend:

Unmodified
Added
Removed
Modified
  • InstalledAppsRevision

    v1 v1  
     1After a long two-day sprint on this, hitting road-block after road-block, we've learned a whole lot.  Here's where we are:
     2
     3== Impetus ==
     4During the state of Django talk, Adrian put up a slide showing an INSTALLED_APPS setting like this:
     5{{{
     6    INSTALLED_APPS = Apps(
     7       app('django.contrib.admin'),
     8       app('project.app', name='polls'),
     9    )
     10}}}
     11The idea is to allow more robustness and extensibility in the INSTALLED_APPS.  We came into this thinking it would be rather simple, but after a while, that was seen to be anything but the case.
     12
     13== Design Goals ==
     14Allow change of name of third-party app
     15Allow change of db_prefix of third-party app
     16Allow multiple instances of an app with different names, db_prefix, etc.
     17
     18== Initial Plan ==
     19db.models.loading becomes core.apps. db.models.loading is kept only for backwards compatibility, redirecting to core.apps.
     20AppCache becomes InstalledApps
     21App class added to hold name, path, db_prefix, etc.
     22settings.INSTALLED_APPS becomes instance of InstalledApps, and converts every item to an App instance if it is a string.
     23{{{
     24settings.INSTALLED_APPS = ('django.contrib.auth',
     25                           App('django.contrib.admin', name='SuperAdmin'),
     26                           App('myapp', name='Wow', db_prefix='pref'))
     27}}}
     28
     29After accessing settings this becomes (pseudo):
     30{{{
     31InstalledApps(App(path='django.contrib.auth', name='auth'),
     32              App(path='django.contrib.admin', name='SuperAdmin'),
     33              App(path='myapp', name='Wow', db_prefix='pref'))
     34}}}
     35
     36For backwards compatibility, set model._meta.app_label to specified name.
     37Going forward, set model._meta.app to App instance, use model._meta.app.name, model._meta.app.db_prefix, etc.
     38
     39Provide signal when InstalledApps is finished loading apps.
     40
     41Multiple instances of an app would NOT be solvable with this, so long as we are attaching and consuming this metadata via model._meta (since model classes would still be shared by the instances). No approaches that didn't herald the return of magic were floated for this. This issue is most likely shared by any multiple-database solution that hopes to allow the same models to be used in different contexts against different databases, so that work may provide a useful solution here as well.
     42
     43
     44== Issues Found During Dev ==
     45Today model._meta.app_label is implicitly forced to be the filesystem dir name above models.
     46
     47Currently model._meta.app_label is heavily overloaded, acts as:
     48 * Admin app display name (by .title())
     49 * Admin permissions prefix
     50 * DB table creation prefix
     51 * Dumpdata/Loaddata fixture prefix identifier
     52 * When explicitly set, used to associate models elsewhere in the app structure.
     53 * RelatedObject explicit cross-app identification.
     54 * contrib.contenttypes identification
     55
     56Some of these should remain in the developer's control (model association, cross-app model id).
     57Some of these should be in the installer's control (admin name, db table prefix).
     58Some of these should use new db_prefix instead (table creation, fixtures?).
     59Some of these it's not clear (contenttypes, permissions).
     60
     61Keeping the interfaces of get_apps, get_models, etc is problematic as some of these just take a models module (and determine the app label by the fs dir name), or return the models module. It would be preferrable if these took and returned App instances (which would have a .module attribute), but with larger compatibility ramifications.
     62
     63Initial attempt at resolving these differences was to have InstalledApps keep two app->models dicts, one by module_name (old app_label) and one by app.name (specified in settings). This lead to a separation between get_model and get_model_from_module_name, the latter used for model association etc that should remain under the original app developer's control.
     64
     65Populating the by-app.name mapping is hackish, since it's not knowledge that's available to ModelBase.__new__ for register_models. Instead, after loading each app we find models by the module_name and store matching entries in the app.name dict.
     66
     67Additionally there are a number of places that use the string paths from INSTALLED_APPS:
     68 * management, translation, templatetags/template loaders (to do further imports)
     69 * test.client (to check if sessions are available)
     70
     71These were straightforward to switch to use app.path
     72
     73== Unresolved ==
     74
     75Whether this approach is overall worthwhile given that it does not address installing multiple instances of an app.
     76Whether contenttypes, permissions, etc should use module_name or app.name or an additionally configurable value (either by app developer or installer).
     77How much backwards incompatibility is acceptable in terms of get_apps/get_models/etc, iter(settings.INSTALLED_APPS), other third-party overloading of _meta.app_label.
Back to Top