This defines the Kernel class.

The "kernel" of a Lino site is (like SITE itself) a "de facto singleton", available to application code as SITE.kernel (and its alias for backwards compatibility: SITE.ui).

The kernel is instantiated at the end of the startup process, when the SITE has been instantiated and models have been loaded. It encapsulates a bunch of functionality which becomes available only then.

TODO: Rename "kernel" to "environment". Because "kernel" suggests something which is loaded in first place. That's not true for Lino's "kernel". it should be renamed to lino.core.env (for "environment") because it represents the runtime environment of a Lino application.

(This module's source code is available here.)



Return a list of all choicelists defined for this application.




This is being called at startup.





This is being imported and called from



This is the class of the object stored in Site.kernel.

class lino.core.kernel.Kernel(site)

Bases: object

This is the class of the object stored in Site.kernel.


Obsolete. Was moved to lino.modlib.memo.

property lino_version

This gathers all of the apps version numbers and add them up in order, to use it as modification stamp. Any updates on any of the dependent django apps will increase this collective version number and will be used as a stamp to propagate changes through the system.

This is automatically activated when Site.never_build_site_cache is set to True, supposedly used in a production server.


This is a part of a Lino site startup. The Django Model definitions are done, now Lino analyzes them and does certain actions:


Change on_delete from CASCADE (Django's default value) to PROTECT for foreignkeys that need to be protected.

Protect the foreign keys by removing Django's default behaviour of having on_delete with CASCADE as default.

Basically we protect all FK fields that are not listed in their model's allow_cascaded_delete. With one exception: pointers to the MTI parent of a Polymorphic must not become protected (because Lino handles it automatically, see lino.mixins.polymorphic.Polymorphic.disable_delete()).

Note that this does not protect FK fields that get defined afterwards, e.g. during pre_analyze, e.g. the purchase_account field defined by TradeTypes.purchases in ledger.

Yield a series of (gfk, fk_field, queryset) tuples which together will return all database objects for which the given GenericForeignKey gfk points to the object obj. See also GenericForeignKey fields.

Yield all database objects of this model that have some broken GFK field.

This is a slow query, which does an additional database request for each row. (Is there a possibility to do this in a single SQL query?)

Each yielded object has two special attributes:

  • _message : a textual description of the problem

  • _todo : 'delete', 'clear' or 'manual'

Note: the "clear" action should not run automatically, at least not for lino.modlib.changes.


Run the action, catching some exceptions in order to report them in a user-friendly way.

setup_handle(h, ar)

Additional setup of an actor handle. This is called lazily for every actor handle because it potentially requires other actor handles to be instantiated.

ar is usually None, except for actors with dynamic handle

row_action_button(*args, **kw)

See ExtRenderer.row_action_button()

make_cache_file(fn, write, force=False)

Make the specified cache file. This is used internally at server startup.


This is being imported and called from It is implemented here in order to avoid local imports.


Return a list of all choicelists defined for this application.

Used by

Tested in Introduction to choicelists.


This is being called at startup.

  • Each model can receive a number of "slaves". Slaves are tables whose data depends on an instance of another model (their master).

  • For each model we want to find out the "default table". The "choices table" for a foreignkey field is also currently simply the pointed model's default table. lino.core.model.Model._lino_default_table