Lino and your Django settings

This section explains some basic things about your Django settings and Lino. See also Modifying your local settings.py.

Django settings module

The Django settings module is the most important thing in Django. Almost everything you do with Django requires the settings module to be loaded. Django does that automagically as soon as you import some module which needs the settings. And when that moment arrives, Django needs to know the name of your settings module.

You can specify this either using the DJANGO_SETTINGS_MODULE environment variable or the --settings command-line option of certain admin commands.

To illustrate this, let's open a Python session in an environment with Django installed but without any DJANGO_SETTINGS_MODULE environment variable defined, and then type:

>>> from django.conf import settings

This will pass. But as soon as you want to actually access some attribute of settings, you will get an ImproperlyConfigured exception:

>>> print(settings.DEBUG)  
Traceback (most recent call last):
...
django.core.exceptions.ImproperlyConfigured: Requested setting DEBUG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

Summary

DJANGO_SETTINGS_MODULE

The DJANGO_SETTINGS_MODULE environment variable is expected to contain the Python name of the Django settings module.

The Django settings module must be importable. That is, if DJANGO_SETTINGS_MODULE contains e.g. foo.bar.baz, then Django will do the equivalent of import foo.bar.baz.

settings.py

When we speak about "the settings.py file", then we actually mean the Django settings module. That's because the filename of a Django settings module is often in a file named settings.py. But in reality it can be some arbitrary filename. For example the DJANGO_SETTINGS_MODULE of lino_book.projects.min1 is lino_book.projects.min1.settings.demo. This layout is called a settings package, it is useful when you want to have different variants of settings modules.

How Lino integrates into Django settings

Here is a typical settings.py file of a Lino project:

from foo.bar.settings import *
SITE = Site(globals())
# ... your local settings here

That is, you import the content of some existing Lino project into your local settings module and then define a SITE variable.

SITE

A Lino settings.py file always contains the following line:

SITE = Site(globals())

This line instantiates your local SITE object. Every Lino application requires a setting named SITE which must be an instance of lino.core.site.Site (or a subclass thereof).

The SITE setting is what turns your Django project into a Lino application.

More about this in Introducing the Site class.

Inheriting settings

You might surprise to see the following contruct:

from foo.bar.settings import *

class Site(Site):
    title = "My title"

SITE = Site(globals())

We are just using a feature of the Python language which allows us to define a new class based on an existing class and having the same name as its parent.

Lino's settings.py files are small

Lino helps you to keep settings.py files small because it delegates the responsibility of maintaining default values for Django settings to the application developer.

A typical settings.py file for a Lino site consists of a few lines (plus, on a production site, the lines for defining your DATABASES setting). Compare this to a settings.py file generated by Django's startproject command which contains 120 lines of text (Django version 2.2.4).

>>> from atelier.sheller import Sheller
>>> shell = Sheller()  # will run in a temporary directory
>>> shell("django-admin startproject foo")

>>> shell("wc -l foo/foo/settings.py")
120 foo/foo/settings.py
>>> shell("django-admin --version")
2.2.7

Settings packages

In some projects we use a whole package of settings:

  • settings/__init.py : the base for all modules of this package.

  • settings/demo.py : instantiates a SITE variable and thus is designed to be used directly as a DJANGO_SETTINGS_MODULE.

Site-wide default settings

This section is obsolete. A Lino server configured using getlino can simply define a module with site-wide default settings, and individual sites can decide to import these.

Lino applications (unlike Django projects) have a hook for specifying site-wide default values for their Django settings. This concept is mostly useful on servers where many Lino sites are running (as described in Configuring site-wide default settings). Actually they are not system-wide but environment-wide.

LINO_SITE_MODULE

Each time a Lino process starts (when a lino.core.site.Site gets instantiated), it checks whether an environment variable LINO_SITE_MODULE is exists. And if it does, Lino expects it to be the name of a Python module, will import that module and, if it contains a function named setup_site, will call that function, passing it the Site instance as one and only positional parameter.

For example you can do:

$ export LINO_SITE_MODULE=my_site_options

And then create a file named my_site_options.py somewhere on your PYTHONPATH with the following content:

def setup_site(self):
    self.update_settings(ADMINS=[("John", "john.doe@example.com")])
    self.update_settings(EMAIL_HOST="mail.provider.com")
    self.update_settings(DEBUG=True)
    self.update_settings(ALLOWED_HOSTS=['127.0.0.1'])
    self.use_java = False

By convention we recommend to name that file lino_local.py and to set LINO_SITE_MODULE to lino_local.

Keep in mind

lino_local.py

lino_local.py is a file containing site-wide local settings, i.e. local settings to be applied to all projects.

The file just defines default values, individual projects can still decide to override them.

This file is usually in a directory /usr/local/src/lino/.

Lino will use these settings only if that directory is in PYTHON_PATH and if the project defines an environment variable LINO_SITE_MODULE containing the string lino_local.

Historic note

djangosite_local.py

The djangosite_local.py file was used until 20160109 as a hard-coded LINO_SITE_MODULE. Which had the disadvantage that it was not easy to disable it quickly.

On servers where this was used, when upgrading to a Lino version after 20160109, you should set LINO_SITE_MODULE to the string djangosite_local in order to maintain the old behaviour:

export LINO_SITE_MODULE=djangosite_local