On Apr 8, 5:33 pm, Nick Sandford <nick.sandf...@gmail.com> wrote: > An App Loading mechanism for Django > ==================================== > > About Me > ---------- > Hi everyone, > > My name is Nick Sandford, I'm an electrical engineering student at the > University of Western Australia. > > Background > ----------- > > I haven't been a particularly active contributor to any open source project - > here is where I hope to change that. In my current work at Christ > Church Grammar School we use Django heavily for most of our internal > projects. I've > followed django-dev closely for a couple of years and I have poked around with > its internals on various occasions. > > Plan > ----- > > Implement an improved application loading mechanism into Django. > > Rationale > --------- > > Django current application loading code is inflexible in many cases. There > exists a need for a number of extra features to be added to the way > applications are handled such as: > > * The ability to internationalise application names. > * The ability to customise application names similar to ``verbose_name`` in > ``model._meta`` > * Deploy the same application multiple times in a single project. > * Deploy two different applications with the same name. > * Manage settings within applications. > > Method > ------- > > I don't intend to solve the third dot point of the previous list - it seems > like a difficult problem, possibly to be tackled post-GSoC. What I do intend > to do is to move towards 'application classes' more akin to > ``django.contrib.admin``. > > New syntax in ``settings.INSTALLED_APPS`` will be introduced to address the > previous issues. Some examples of accepted syntax: > > .. sourcecode:: python > > INSTALLED_APPS = ( > 'django.contrib.auth', > app('blog.BlogApplication', 'blog_1', 'My blog', 'app1_'), > app('blog.BlogApplication', 'blog_2', 'Some other blog', 'app2_'), > app(path='tagging.Tagging', verbose_name='My tagging application'), > app('categories', db_prefix='cat_'), > app({'path': 'django.contrib.admin.AdminApplication', > 'label': 'admin', > 'verbose_name': 'Secret Admin'}), > ) > > The ``app`` function will take four arguments, three of which are optional. > These are ``path``, ``label``, ``verbose_name``, and ``db_prefix``. It will > return an instance of an ``Application`` object, which will contain all of an > installed application's information. ``path`` will be the dotted path to a > subclass of ``Application``. The downside is that ``settings.py`` requires > an import, which may be against style rules. > > .. sourcecode:: python > > def app(path, label=None, verbose_name=None, db_prefix='') > if not path or not isinstance(path, basestring): > raise ImproperlyConfigured('Application path must be string.') > application_class = import_module(path) > return application_class(path, label, verbose_name, db_prefix) > > ``INSTALLED_APPS`` will then be a tuple containing strings or ``Application`` > instances. The application loading code will iterate over ``INSTALLED_APPS`` > and construct an internal cache of ``Application`` instances to be used with > ``get_models``, etc. For backwards compatibility, if an element of the tuple > is > a string, an instance of a base ``Application`` class will be created with > sane > defaults (similar to ``app_label`` at the moment). > > The ``Application`` class will be very similar to ``django.contrib.admin``'s > ``AdminSite`` and will hopefully simplify application settings. If you write > views and urls directly on the ``Application`` class itself, instead of an > ``from django.conf import settings`` and subsequent ``settings.API_KEY``, you > could just reference ``self.api_key`` for instance. This wouldn't be the > required, just an optional extra. > > Model classes will get a ``_meta.app`` attribute, which will be an instance > of the model's ``Application`` class. Models should only be associated with > one > application. > > I agree with moving ``django.db.models.loading`` to ``core.apps``, since we'll > no longer require applications to have a ``models.py``. A reference to the > new functions in ``core.apps`` will still live in ``django.db.models.loading`` > for backwards compatibility. > > A subclass of ``Application`` might look like: > > .. sourcecode:: python > > from django.views.simple import direct_to_template > from djang.core.apps import Application > from blog.models import Entry, Category > > class BlogApplication(Application): > models = [Entry, Category] > api_key = 'default' > > def entry_detail(self, slug, request, > template_name='blog/entry_detail.html'): > entry = get_object_or_404(Entry, slug=slug) > context = { > 'entry': entry, > 'api_key': self.api_key, > } > return direct_to_template(request, template_name, context) > > Hurdles > -------- > > There are a list of possible technical issues: > > * Introducing the new ``app`` function requires an import in settings.py > which might not be acceptable behaviour. > * Two applications with the same label. > * Worrying amounts of things that may affect backwards compatibility would > probably need addressing. > > Solutions > ---------- > > We could alternatively introduce a new file into the project, > ``applications.py`` which contains purely application-related setup. This > might > be handy to manage application settings and to ensure ``settings.py`` doesn't > get too full of application-specific settings. This could allow us do > something > like: > > .. sourcecode:: python > > from django.core import apps > from blog import BlogApplication > > class MyBlogApplication(BlogApplication): > api_key = 'testing' > > another_blog = BlogApplication(label='blog2', > verbose_name=_('Another blog'), > api_key='anothertest') > > apps.register(MyBlogApplication, label='blog', verbose_name=_('My blog')) > apps.register(another_blog) > > depending on what people would like more. This could allow us not to touch > ``settings.INSTALLED_APPS`` at all. > > To solve the 'two applications named auth' problem, the ``AppCache`` keeps > track of application instances, not ``app_label``. For the case of two > applications with the same name, ``get_app`` should return a tuple containing > both application instances with that name. To ensure a single application > instance is returned with ``get_app``, another argument - ``path`` should be > added. ``get_models`` and ``get_model`` would take an application instance > and return models on that instance. This might affect the admin's handling of > applications. > > Timeline > --------- > > 1) Implement the ``Application`` class. -- 2 weeks > 2) Move ``django.db.models.loading`` to ``django.core.apps`` and refactor > ``get_app``, ``get_model``, etc. -- 1 week > 3) Modify the admin, management, translation, templatetags, templateloaders > to use ``app.path`` -- 1 week > 4) Testing and documentation -- 3 weeks > 5) Bug fixes and backwards incompatibility problems -- 1 week > 6) Time permitting possibly tackle the multiple instances of the same app > problem. (about 2 weeks). > > Any feedback would be greatly appreciated, sorry for the late application and > good luck to all the other applicants :) > > Thanks, > Nick
Have you looked at the patch on ticket 3591 which does some of this already? Would you be using it as a starting point? Regards, Vinay Sajip -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-develop...@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.