| | 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. |