User Tools

Site Tools


This is an old revision of the document!

Introduction to using Django with NAV

Since the release of 3.4.0 parts of NAV have been using the Python web framework Django, starting with the new IP Device Info app.

This introduction to using Django with NAV assumes that the reader is familiar with Django, i.e. have read the Django tutorial and knows his way around the Django documentation.

As NAV has not used Django from the very beginning, NAV does not strictly follow the Django convention of multiple apps with their own models, views, etc. To plug NAV into the Django framework some glue is needed. This glue and other common Django-related code is located in the nav.django Python package, which is located in subsystem/lib-python/src/nav/django.


The usual Django settings file is located at nav.django.settings. The end-users does not need to modify this settings file when deploying NAV, as all options are derived from existing NAV configuration in i.e. the files nav.conf and db.conf.

Note that there is no INSTALLED_APPS setting. NAV does not use this setting at all, due to a different file organization than what Django expects. Following from this, Django does not have a concept of what is an app in NAV. An app is just defined in the minds of the developers. This also means that NAV to a very little degree may take advantage of the executable, including features like syncdb for creating database tables for new apps.

URL configuration

In nav.django.urls the root URL configuration for all things Django in NAV is located. The URLconf is roughly divided in two. The first part delegates various URL namespaces, like /ipdevinfo/, to the corresponding Django apps and their own URLconfs. The second part is URL patterns for non-Django NAV subsystems, like the report subsystem. The second part is used by Django apps to link to non-Django apps, through the use of the url template tag or the reverse() function, instead of using the archaic nav.web.urlbuilder.


Since before Django, NAV has been using the Cheetah template system. To enable the use of Django templates for Django apps, while still integrating with the existing template hierarchy of NAV, some shortcut functions has been created in nav.django.shortcuts. At the time of writing, the shortcuts are render_to_response(), object_list(), and object_detail(). render_to_response() is analogous to the well known django.shortcuts.render_to_response(), and object_list() and object_detail() are analogous to functions in django.views.generic.list_detail.

The difference between the original functions from Django and the ones provided in nav.django.shortcuts is that the NAV versions take an additional first argument, namely cheetah_template_func. cheetah_template_func is assumed to be a Cheetah template function, which returns a Cheetah template with a content_string variable. The shortcuts takes the content which Django normally would have returned, and inserts it into the content_string variable of the Cheetah template. In other words, a Django template is rendered as usual, and then the result are wrapped into a Cheetah template.

Context processors

At the time of writing, nav.django.context_processors only contains one context processors: debug. If Django is run in debug mode, this context processors appends a sql_queries variable to the context of all templates, containing all SQL queries executed to generate the current page. This is useful for optimizing the use of the Django ORM.

The Django convention places models in the apps where they belong the most. In NAV, all models are located centrally in the nav.models package. Usually, one creates the models first and then generates the database from the models using the previously mentioned syncdb feature. Since NAV existed long before Django, our models was created for an existing legacy database through the use of Django's database introspection and numerous hours of hard manual labor to clean up the models, adding __unicode__() methods, etc.


The models was split in as many modules as possible, only limited by interdependencies between the models. This resulted in the following seven modules:

  • cabling: models for mapping switch ports to physical rooms.
  • event: models related to event and alert queues.
  • manage: all models from the old manage database which were not possible to split out to own modules, including the most important models like Netbox, SwPort, and GwPort.
  • msgmaint: models related to the message and maintenance subsystems.
  • oid: models related to OID mappings.
  • rrd: models related to RRD files and data sources.
  • service: models related to services.

Of these the manage module is by far the most used and probably of the highest quality. All users of the models should have a look through their definitions to be familiar with how they are mapped to the legacy database using the db_column and db_table arguments, and what methods like get_absolute_url() and __unicode__() are available to the user.


In nav.models.__init__ the DJANGO_SETTINGS environment variable is set to nav.django.settings. As a result of this, one can simply import the models one wants to work with and just use them, without regard to database connections, etc. An example follows:

>>> from nav.models.manage import Netbox
>>> Netbox.objects.filter(sysname__endswith='').count()
>>> n = Netbox.objects.filter(sysname__endswith='')[0]
>>> n
>>> n.up_since
datetime.datetime(2008, 5, 30, 15, 36, 50, 350000)
>>> n.organization
<Organization: uninett (UNINETT)>

The workings of a Django app in NAV

To create a new NAV tool/Django app, the easiest approach is probably to start with copying an existing app, like subsystem/ipdevinfo/. This section explains what the different parts of the ipdevinfo app is, and how it is plugged into the rest of NAV, by following the life cycle of a HTTP request and response.

File structure

Using the ipdevinfo app as an example. The nav/ folder contains all runnable Python code, and nothing else. It is installed to the Python path. nav/web/ipdevinfo/ (nav.web.ipdevinfo Python package after installation) contains all the Django code for the app, including URLconf for the apps URL scope, views, forms, etc.

In addition nav/web/templates/ contains a Cheetah template (not runnable Python code, but it will be compiled to a runnable Python file during installation) which is used to wrap around the Django templates. The Django templates themselves are not runnable Python code, but HTML files with some additional syntax, and are thus available directly in the templates/ folder, not within the nav/ folder. The Django templates are installed to a templates/ folder next to the python/ folder where all installed Python code goes. Typically this is /usr/local/nav/lib/templates/.

Further, the file ipdevinfo.tool defines the name, description, icon and URL of the IP Device Info tool in NAV's toolbox. The file htaccess is the only file which is installed into the ipdevinfo/ folder in the web server's document root. It simply states that all URLs starting with i.e. are to be handled by a Python program, namely Django's mod_python handler, using nav.django.settings as configuration. In other words, the htaccess file should be identical for all Django apps in NAV.

How to install everything mentioned here is defined in

Request/response life cycle


Future enhancements



NAV uses sessions for keeping track of logged in users. Currently, we are not using django.contrib.sessions, but are still using plain old mod_python sessions. The easiest way to get hold of the mod_python session in views is to use request._req.session, where request._req is the traditional mod_python request object.

Main template in Django

TODO: Replace wrapping Django templates in Cheetah templates.

Unit testing


devel/django_introduction.1218791773.txt.gz · Last modified: 2008/08/15 09:16 by jodal