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.

Reply via email to