| 1 | This is an attempt to bring together the current state and long term plans of how |
| 2 | application loading is done in Django, what it could do, and why. |
| 3 | |
| 4 | == Application loading refactor == |
| 5 | |
| 6 | At present application loading is handled in different ways through Django. |
| 7 | Because of some of the limitations of Python, and some peculiarities of how |
| 8 | models work, modules should not be reimported. Consequently Django maintains |
| 9 | a global static, called the application cache. Models are imported from the |
| 10 | application cache transparently when interacting with the database. But |
| 11 | applications listed in `INSTALLED_APPS` contain more than just models. Some |
| 12 | contain template tags, `admin.py` files, `search_indexes.py` files from |
| 13 | haystack, template folders and many other features which applications use to |
| 14 | inspect each other, or to contribute objects to a site-wide collection. |
| 15 | |
| 16 | For the majority of applications, even reusable applications, anything more |
| 17 | than the current system is unnecessary. Models are automatically registered, |
| 18 | template tags can be loaded, and templates are available. (Tests are also |
| 19 | available but this is a separate issue.) |
| 20 | |
| 21 | However, not every application has all of these components - there are many |
| 22 | useful pluggable applications which do not contain models, but must still be |
| 23 | registered in `INSTALLED_APPS`. A simple example is `django-pagination` - |
| 24 | which consists of a single template tag. This module must ship with an empty |
| 25 | `models.py` module to allow it to be registered as an installed app, for that |
| 26 | template tag to be available. |
| 27 | |
| 28 | The problem is even more difficult for ''"meta-applications"'' - that is to say |
| 29 | applications which exist solely to interact with other applications. The |
| 30 | canonical example of this is the django admin, but there are many third party |
| 31 | applications which do a similar thing. Haystack (the search engine framework) |
| 32 | is a good example. Also there are applications which have a plugin archicture, |
| 33 | whereby adding a second application to installed apps changes the behaviour of |
| 34 | the first application. All of these third party systems have implemented their |
| 35 | own ways to do this, with varying degrees of success. |
| 36 | |
| 37 | This is an opportunity for Django to do something great for the third party |
| 38 | application community. It will be a very powerful tool, and opens up a range of |
| 39 | magical things which could be done. App loading is magical, but Magic is not |
| 40 | always a bad thing - most Django developers are very pleased they don't have to |
| 41 | individually register every model with Django as they do to register a model |
| 42 | with the admin. You just put it in the `models.py` file and it works! This |
| 43 | will allow the magic to be more explicit, and ultimately more consistent |
| 44 | between third party applications. |
| 45 | |
| 46 | This is a big change, and almost redefines what an "App" is within Django. To |
| 47 | my mind, an app was originally intended to be a fairly self contained part of |
| 48 | the system, normally in fact a self contained part of the ''Web site''. |
| 49 | |
| 50 | |
| 51 | === Specification === |
| 52 | |
| 53 | Here is a specification of what an application is, and what it can do. Perhaps |
| 54 | not all of these points need to be implemented to be able to integrate this |
| 55 | refactor into core, but they should be considered to avoid future backwards |
| 56 | incompatibilities. |
| 57 | |
| 58 | * An application is a self contained piece of code which '''contributes''' |
| 59 | something to the site. It may contibute any number of the following: |
| 60 | * models |
| 61 | * templates |
| 62 | * template tags |
| 63 | * static files |
| 64 | * admin configuration |
| 65 | and these are just (some of?) the things which are picked up on by other |
| 66 | parts of the Django core. Other things (seach indexes, migrations etc) may |
| 67 | also be contributed by the application, and processed by other applications. |
| 68 | |
| 69 | '''Note''' Some things are explicitly registered in settings, such as middleware, |
| 70 | database routers and cache backends. These things may be contained within |
| 71 | an application's code base, but they will not be registered automatically |
| 72 | by the presence of that application in the `INSTALLED_APPS`. |
| 73 | |
| 74 | * An application may contain urls and views. These will generally be |
| 75 | explicitly registered, but some applications may choose to attach dynamic |
| 76 | urls offer a way of getting the urls from the application rather than |
| 77 | directly (similar to how the admin does to it's site class). |
| 78 | |
| 79 | * An application may modify another application. That is to say, an application |
| 80 | may provide an interface on it's application class for other applications to |
| 81 | modify it. This will facilitate a plugin architecture. A classic example of |
| 82 | where this will be useful is a Content Management System. |
| 83 | |
| 84 | * An application may depend on the presence of another application. It is |
| 85 | preferable for the application to depend on a defined ''contract'' with another |
| 86 | application, rather than explicity depend on that application. This should |
| 87 | allow applications to be more loosely coupled, leading potentially to |
| 88 | pluggable auth/messages applications. It also allows such applications to be |
| 89 | tested perhaps without the presence of the dependant app - a mocked object |
| 90 | may suffice. |
| 91 | |
| 92 | * An application may inspect other applications to gather information about |
| 93 | them. The system should provide tools to easily and safely access this |
| 94 | information, whether it is accessing a folder or a python module. Where |
| 95 | possible, we should modify parts of Django core & contrib to use this system. |
| 96 | Examples would include the app directories template loader, admin site and |
| 97 | template tag libraries. |
| 98 | |
| 99 | * An exact copy of an application can be deployed within the same project by |
| 100 | changing its label. This will have some subtle issues regarding imports. |
| 101 | |
| 102 | |
| 103 | === Implementation plan === |
| 104 | |
| 105 | Application class. Talk about what APIs would bee needed on that class to |
| 106 | achieve the above. Separate by the above points. Ideally, does not need to be |
| 107 | contained within the python module it relates to (thus allowing me to subclass |
| 108 | an app's Application Class in my own project to tweak how it works, this may or |
| 109 | may not be better than passing configuration options) |
| 110 | |
| 111 | Application cache. Discuss what hooks this would need to provide, including |
| 112 | signals, for the above to work. |
| 113 | |
| 114 | Examine any backwards incompatibilities which may result. The app refactor |
| 115 | itself shouldn't introduce any, but the new functionality which it offers and |
| 116 | the resulting changes in other applications such as `contrib.auth` may need |
| 117 | deprecation paths. |
| 118 | |
| 119 | |
| 120 | === Current status === |
| 121 | |
| 122 | Preston has merged master into the existing branch with work done by Jannis and |
| 123 | Arthur. (https://github.com/ptone/django/commit/8722bdcc17293baa8b527ae7169b9a465e728d41) |
| 124 | |
| 125 | We need to evaluate which of the current features are implemented, and which are |
| 126 | not. |
| 127 | |
| 128 | Update tests so that everything passes again, including outside of the appcache |
| 129 | tests. |
| 130 | |
| 131 | Try to work out which parts of the implementation plan are tangential to |
| 132 | each other, and therefore could easily be worked on by other people. |