Translation(s): none


Django Packaging Guidelines

Proposal for packaging guidelines of Django applications and projects.

Problem Statement

There is no strong guideline for packaging Django applications and projects for Debian. Existing guidelines for web applications do not fit Django very well.

Goals

The goals can be summarized as the best, practical approach to supporting Django web applications out of the box.

Packaging Django Applications

Django applications, despite the name are a Django equivalent to Python package. It's a immutable container of code, templates and read-only web resources (images, scripts, etc). The guide defines:

Packaging Django Projects

Django projects are containers for applications, settings, templates and resources. They are the practical means of running Django code. The guide defines:

Packaging Django Applications

Code, documentation and i18n

For the most part, Django applications differ very little from python packages. This guide recommends that the following components adhere to standard, documented packaging guidelines:

The rationale for this choice is that all Django applications are just python packages and thus should be treated exactly like python packages. Documentation and translation files are already well established and should not diverge for unspecified reasons.

Templates

Packaging of templates should follow the same guidelines as packaging the actual source code. This guide recommends that templates should be installed in /usr/lib/python2.*/packagemodule/templates, that is, they should be installed in the "templates" directory relative to the directory with the python package.

The rationale for this choice is:

Static files

Packaging of Django static files is more complex. This is caused by the semantics of the static files that Django 1.3 introduced (and that can be used in 1.2 installations with the django-staticfiles standalone package).

Historically Django had a concept of media files that a project would have access to. Those media files included both user uploaded (or application generated) content as well as read-only files distributed with each application. With Django 1.3 this changes with the introduction of the staticfiles contrib module. In this model static files are distributed by each application and are finally assembled together to a single directory when the project is configured for runtime. In that model static files are source resources that are built at configuration time and can vary when the administrator reconfigures the application.

The static files of a particular application should be stored in the static directory relative to the application sources. This is in compliance with upstream recommendation.

Running auto tests at build time

When using dehelper with dh-python2 and pybuild, you may need to override the dh_auto_test, in a way similar to this (see pybuild manpage):

override_dh_auto_test:
        PYBUILD_SYSTEM=custom \
        PYBUILD_TEST_ARGS="cd {build_dir}; django-admin test --settings=YOURMODULE.test_settings --pythonpath=. [YOURMODULE.tests]" \
        dh_auto_test

Where YOURMODULE is the top-level dir which contains a specific Django settings named test_settings.py and contains a tests/ subdir for the auto tests to pass.

Packaging Django Projects

Code and Settings

Projects actually have some code although not as much as typical applications do. A the very least each project will have urls and settings. This guide recommends that all project files should be installed to a private python package not to pollute the namespace. The settings should be PACKAGE.settings, the URLS should be PACKAGE.urls where PACKAGE is the name of the Debian package containing the Django project.

This guide does not define how settings should work, several approaches are possible:

  1. Ship examples and require the administrator to finalize the deployment
  2. Ship a pre-cooked immutable settings file that looks at configuration file in /etc/PACKAGE/, optionally managed by debconf

Optionally the settings file may be pre-cooked for web server integration so that the administrator can install and use a package immediately without having to configure the web server as a separate step.

Project wide-templates

Project wide templates are template files that may override any templates shipped with individual applications. This guide recommends that project templates be treated exactly like application templates with two notable differences:

Project database settings

Database settings should follow dbconfig-common conventions. In particular if the settings file is pre-cooked for debian and will allow the application to work out of the box then it should integrate with debconf to obtain the appropriate database settings.

TODO: Should the project package depend on PACAKGE-database provided by PACKAGE-mysql PACKAGE-postrgres and PACKAGE-sqlite similarly to the way redmine is packaged today? This would allow to split database dependencies to appropriate sub-packages.

Packaging of manage.py

Packaging of helper programs (such as the venerable manage.py) should follow package-private executables policy. That is, I recommend to store such programs in /usr/lib/PACKAGE where PACKAGE is the name of the Debian package containing the Django project. manage.py should be extended to deal with the private module path and extend sys.path with appropriate pathname ensuring that PACKAGE can be imported properly.

Static Files Cache

Post-install maintainer script should build a catalog of files used by a particular project based on the project configuration. The catalog should be stored in /var/lib/PACKAGE/static where PACKAGE is the name of the Debian package with a Django project. The actual files should be symlinked to relevant media files distributed by each application or project package using manage.py build_static --link for django 1.2 or manage.py collectstatic --link for django 1.3).

The rationale is twofold: First we allow any application to ship any kind of resources needed without having to bother with project configuration, second we allow the administrator to (optionally) change the configuration of the project and add more applications thus triggering the need to reconfigure the static files cache.

Serving Static Files

Static files should be served by a non-django application server (that is, they should never be served by Django directly). This is done for efficiency and security as Django officially discourages this and in fact disables serving of static files through django unless DEBUG development mode is enabled.

This guide recommends that project packages should install relevant web server integration files that would expose the static file cache in an appropriate manner.

Serving Media Files

Media files should be served similarly to the way static files are served, that is, by a dedicated web server and not by the application server. This guide recommends that media files should be stored in /var/lib/PACKAGE/media where PACKAGE is the name of the Debian package with a Django project.

This guide recommends that project packages should install relevant web server integration files that would expose media files in an appropriate manner.

Unresolved issues

Open Questions

The following questions are open and are a subject of further discussion and analysis. This guide does not attempt to define the best method of doing any of those topics.

Optional Guidelines

Implementation

A work-in-progress implementation is being written. The code can be obtained with Bazaar from Launchpad. The branch is currently located in lp:~zkrynicki/+junk/django_hello.