.. _howto.settings: ======================================== Modifying your local :file:`settings.py` ======================================== Every :term:`Lino site` is defined by a :term:`Django settings module`, usually defined in a file named :xfile:`settings.py`. A minimal Lino :xfile:`settings.py` contains something like this:: from foo.bar.settings import * SITE = Site(globals()) # more local settings here That is, you import the default settings of some :term:`Lino application` into your local settings module, including a :class:`Site` class, then you *instantiate* that :class:`Site` class and store the instance in a *variable* named :setting:`SITE`. Every :term:`Lino site` requires a setting named :setting:`SITE`. .. setting:: SITE The instance of :class:`lino.core.site.Site` (or a subclass thereof) that defines the *application* that is running on this *site*. The :setting:`SITE` setting is what turns a Django project into a :term:`Lino site`. As a :term:`site maintainer` you can override many settings by modifying the :xfile:`settings.py` file generated by :cmd:`getlino startsite`. To edit your local :xfile:`settings.py` file, go to the project directory and start your preferred editor on it:: go mysite nano settings.py After modifying your :xfile:`settings.py` you must run :xfile:`reload_services.sh` to restart all services that use Lino. The :xfile:`settings.py` file must be valid Python syntax. One pitfall if you have no experience with Python is that *indentation* is important. Also make sure that your text editor doesn't replace spaces by tabs. In case of doubt, before restarting the server, you may issue the following command to test whether your :xfile:`settings.py` is okay:: $ python manage.py validate Inheriting settings =================== You might be surprised to see the following construct:: from foo.bar.settings import * class Site(Site): title = "My title" SITE = Site(globals()) We are just using a feature of the Python language that allows us to define a new class based on an existing class and having the same name as its parent. A :xfile:`settings.py` file generated by getlino also adds the following:: def get_plugin_configs(self): yield super(Site, self).get_plugin_configs() # example of local plugin settings: # yield ('ledger', 'start_year', 2018) That is, you override the :meth:`lino.core.site.Site.get_plugin_configs` method. Lino dynamically creates your Django settings ============================================= The first argument of the instantiator must be the global namespace of your settings module (`globals() `__). Lino uses this to fill "intelligent default values" to your settings module's global namespace. In other words, Lino is going to automatically set certain Django settings. Including for example :setting:`INSTALLED_APPS` and :setting:`DATABASES`. Note that Lino writes to your settings module's global namespace only while the Site class gets *instantiated*. So if for some reason you want to modify one of the settings, do it *after* your ``SITE=Site(globals())`` line. You've maybe heard that it is not allowed to modify Django's settings once it has started. But there's nothing illegal with this here because this happens before Django has seen your :xfile:`settings.py`. Lino does more than this. It will for example read the `__file__ `__ attribute of this, to know where your :file:`settings.py` is in the file system. Here are some of the Django setting for which Lino sets default values: - :setting:`DATABASES` : a SQLite database in a file :file:`default.db` in your project directory. On a production server you are of course going to set your own :setting:`DATABASES`, but this default value is the best choice for beginners. - :setting:`USE_L10N` and :setting:`LANGUAGE_CODE` (see :doc:`/dev/languages` for details on these) - :setting:`LOGGING` : See :func:`lino.utils.log.configure`. - The :setting:`ROOT_URL` setting and the files :file:`urls.py` and :file:`polls/views.py` generated by Django are not necessary. With Lino you don't need to worry about URLs and views because Lino defines them for you. Lino's :xfile:`settings.py` files are small =========================================== Lino helps you to keep :xfile:`settings.py` files small because it delegates the responsibility of maintaining default values for Django settings to the :term:`application developer`. A typical :xfile:`settings.py` file for a Lino site consists of a few lines (plus, on a production site, the lines for defining your :setting:`DATABASES` setting). Compare this to a :file:`settings.py` file generated by Django's :manage:`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") #doctest: -SKIP 3.1.4 .. _settings: The Django settings module ========================== The :term:`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 a Python process accesses the settings. And when that moment arrives, Django needs to know the name of your settings module. You can specify this name either using the :envvar:`DJANGO_SETTINGS_MODULE` environment variable or the `--settings` command-line option of most :term:`django-admin commands `. To illustrate what happens when Django doesn't know the settings module, let's open a Python session in an environment with Django installed but *without* any :envvar:`DJANGO_SETTINGS_MODULE` environment variable defined, and then type: .. Make sure that DJANGO_SETTINGS_MODULE isn't set because otherwise Django raises another exception: >>> import os ; u = os.environ.pop('DJANGO_SETTINGS_MODULE', None) >>> from django.conf import settings This will pass. We said *almost* everything requires the settings to be loaded. You may import the :mod:`django.conf.settings` module. But as soon as you want to actually access some attribute of this module, you will get an `ImproperlyConfigured` exception: >>> print(settings.DEBUG) #doctest: +IGNORE_EXCEPTION_DETAIL 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. A Django settings module must be importable. That is, if :envvar:`DJANGO_SETTINGS_MODULE` contains e.g. ``foo.bar.baz``, then Django will do the equivalent of ``import foo.bar.baz``. Settings packages ================= We use to speak about "the :xfile:`settings.py` file", but in reality the :term:`Django settings module` can be in some arbitrary filename. Some Django sites use a layout called a `settings package `_, which is useful when you want to have different variants of settings modules. In some projects we use a whole package of settings: - :file:`settings/__init.py` : the base for all modules of this package. - :file:`settings/demo.py` : instantiates a :setting:`SITE` variable and thus is designed to be used directly as a :setting:`DJANGO_SETTINGS_MODULE`. .. _server_wide_settings: Site-wide default settings ========================== A :term:`Lino server` configured using :ref:`getlino` can provide a module with server-wide default settings for this server, and individual sites can decide to import these. Such a module (despite the fact that it is also in a file named :xfile:`settings.py`) is not a :term:`Django settings module`. Here are some typical Django settings for which a server-wide default value makes sense: :setting:`ADMINS` :setting:`EMAIL_HOST` :setting:`SERVER_EMAIL` :setting:`DEFAULT_FROM_EMAIL` :setting:`STATIC_ROOT` :setting:`TIME_ZONE` Summary ======= .. glossary:: Django settings module A module that is imported by a Python process when it uses Django. It is just a Python module with module-level variables, most of them upper-case. It is usually stored in a file named :xfile:`settings.py`. See https://docs.djangoproject.com/en/3.1/topics/settings/ .. envvar:: DJANGO_SETTINGS_MODULE The environment variable that is expected to contain the *Python name* of the :term:`Django settings module`. .. xfile:: settings.py The conventional name of a file that contains a :term:`Django settings module`. Note that a file of this name also can contain :ref:`server_wide_settings` or the :class:`Site` class of an application (:doc:`/dev/site`).