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
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.
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.
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.7).
>>> 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 3.0rc1
Settings packages¶
In some projects we use a whole package of settings:
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.
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 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
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