users : user management

This document describes the lino.modlib.users plugin, which in Lino replaces django.contrib.auth. See also User management à la Lino for getting started with user management.

This is a tested document. The following instructions are used for initialization:

Code examples in this document use the lino_book.projects.min1 demo project:

>>> from lino import startup
>>> startup('lino_book.projects.min1.settings')
>>> from lino.api.doctest import *


If you wonder why Lino replaces Django's user management and permission system, see Lino has its own user management.

The site administrator can optionally specify a date when a user started or stopped to be active.

class lino.modlib.users.Users

Base class for all tables of User.

class lino.modlib.users.AllUsers

Shows the list of all users on this site.

class lino.modlib.users.UsersOverview

A variant of Users showing only active users and only some fields. This is used on demo sites in admin_main.html to display the list of available users.

class lino.modlib.users.User

Django model used to represent a user.


No longer used. See as is_authenticated.


This is always True. Compare with AnonymousUser.is_authenticated.



Must be unique and cannot be empty.


The nickname or initials of this user. This does not need to be unique but should provide a reasonably identifying function.


The user type given to this user. Users having this field empty are considered inactive and cannot log in.

See also Introduction to permissions.


Pointer to the Partner instance related to this user.

Every user account can optionally point to a partner instance which holds extended contact information. One partner can have more than one user accounts.

This is a DummyField when lino_xl.lib.contacts is not installed or when User is a subclass of Partner .


A virtual read-only field which returns the Person MTI child of the partner (if it exists) and otherwise None.


Not used in Lino.


Returns either the initials or get_full_name().


Return the first_name plus the last_name, with a space in between. If both fields are empty, return the initials or the username.

def get_row_permission(self, ar, state, ba)

Only system managers may edit other users. See also disabled_fields().

One exception is when AnonymousUser is not readonly. This means that we want to enable online registration. In this case everybody can modify an unsaved user.


If start_date is given, then the user cannot sign in before that date. If end_date is given, then the user cannot sign in after that date.

These fields are also used for userstats: User statistics.

User types

class lino.modlib.users.UserTypes

The list of user types available in this application.

You can see the user types available in your application via Explorer ‣ System ‣ User Types.

Every application should define at least three named user types:

class lino.modlib.users.UserType

Base class for all user types. Any instance if this represents a possible user type.


The role of users having this type. This is an instance of <lino.core.roles.UserRole> or some subclass thereof.


Whether users of this type get only write-proteced access.


A subset of languages which should be hidden for users of this type. Default value is hidden_languages. This is used on multilingual sites with more than 4 or 5 languages.


Return a context manager so you can write code to be run with this as the current user type:

with UserTypes.admin.context():
    # some code

User roles and their usage

class lino.modlib.users.UserRoles

Shows a list of the user roles used in this application together with the user type that have them.

This table can help when designing the list of user types and what permissions each of them should have.


======================== ===== ===== =====
 Name                     000   100   900
------------------------ ----- ----- -----
 cal.GuestOperator              ☑     ☑
 comments.CommentsStaff               ☑
 comments.CommentsUser          ☑     ☑
 contacts.ContactsStaff               ☑
 contacts.ContactsUser          ☑     ☑
 excerpts.ExcerptsStaff               ☑
 excerpts.ExcerptsUser          ☑     ☑
 notes.NotesStaff                     ☑
 notes.NotesUser                ☑     ☑
 office.OfficeStaff                   ☑
 office.OfficeUser              ☑     ☑
 polls.PollsAdmin                     ☑
 polls.PollsUser                ☑     ☑
 xl.SiteAdmin                         ☑
 xl.SiteUser                    ☑
======================== ===== ===== =====

The table doesn't show all user roles, only those that are "meaningful".

Where meaningful means: those which are mentioned (either imported or defined) in the global context of the user_types_module. We tried more "intelligent" approaches, but it is not trivial for Lino to guess which roles are "meaningful".

User sessions

class lino.modlib.users.Sessions

Show a list of all user sessions.

See User sessions.

Authorities : let other users work in your name

class lino.modlib.users.Authority

Django model used to represent a authority.


The user who gives the right of representation. author of this authority


The user who gets the right to represent the author

The current user type

This is used by lino.utils.jsgen, i.e. when generating the linoweb.js file for a given user type.

Plugin configuration

class lino.modlib.users.Plugin

The sessions limit for this site. The default value -1 means that there is no limitation. Setting this to 0 will prevent any new login attempt and might be useful as a temporary value before shutting down a site.


Whether this site offers online registration of new users.


class lino.modlib.users.Helper

Somebody who can help others by running AssignToMe action.

class lino.modlib.users.AuthorshipTaker

Somebody who can help others by running TakeAuthorship action.


class lino.modlib.users.SendWelcomeMail

Send a welcome mail to this user.

class lino.modlib.users.ChangePassword

Change the password of this user.


The current password. Leave empty if the user has no password yet. And SiteAdmin users don't need to specify this at all.


The new password.


The new password a second time. Both passwords must match.

class lino.modlib.users.SignIn

Open a window which asks for username and password and which authenticates as this user when submitted.

class lino.modlib.users.SignOut

Sign out the current user and return to the welcome screen for anonymous visitors.

Model mixins

class lino.modlib.users.Authored

The list of required roles for getting permission to edit other users' work.

By default, only SiteStaff users can edit other users' work.

An application can set manager_roles_required to some other user role class or a tuple of such classes.

Setting manager_roles_required to [] will disable this behaviour (i.e. everybody can edit the work of other users).

This is going to be passed to has_required_roles of the requesting user's profile.

Usage examples see lino_xl.lib.notes.models.Note or


No longer used. The name of the field that defines the author of this object.

class lino.modlib.users.UserAuthored

Inherits from Authored.

Mixin for models that have a user field which points to the "author" of this object. The default user of new instances is automatically set to the requesting user.


The author of this object. A pointer to lino.modlib.users.models.User.

class lino.modlib.users.StartPlan

Whether to run Plan.update_plan() after starting the plan.

class lino.modlib.users.UserPlan

Mixin for anything that represents a "plan" of a given user on a given day.

What a "plan" means, depends on the inheriting child. Usage examples are an invoicing plan (lino_xl.lib.invoicing.Plan) or an accounting report ():class:lino_xl.ledger.Report).

The mixin makes sure that there is only one database instance per user. A plan is considered a low value database object to be reused frequently.

Inherits from UserAuthored.


The user who owns and uses this plan.


This date of this plan. This is automatically set to today each time the plan is called or updated.

run_start_plan(self, user)

Return the database object for this plan and user. or create

update_plan(self, ar)

Implementing models should provide this method.

class lino.modlib.users.UpdatePlan

Build a new list of suggestions. This will remove all current suggestions.


Verify whether the help_text of the change_password action is set:

>>> ba = rt.models.users.AllUsers.get_action_by_name('change_password')
>>> print(ba.action.help_text)
Change the password of this user.

Verify whether #3766 is fixed:

>>> show_choices('robin', '/choices/users/Users/partner')
Altenberg Hans
Arens Andreas
Õunapuu Õie
Östges Otto
>>> show_choices('robin', '/choices/users/Users/user_type')
000 (000 (Anonymous))
100 (100 (User))
900 (900 (Administrator))


The following concepts have been covered by this documentation page.


A human person who can sign in on a given site.

user type

The type of a user, which mainly defines the user's permissions, i.e. what functionalities and data they can access. See User types.


The fact that one user gives another user the right to "represent" them, i.e. to act in their name.

User types module

The default value for Site.user_types_module is None, meaning that permission control is inactive: everything is permitted. But note that Site.set_user_model() sets it to lino.core.user_types.

This must be set if you want to enable permission control based on user roles defined in Permittable.required_roles and UserType.role.

If set, Lino will import the named module during site startup. It is expected to define application-specific user roles (if necessary) and to fill the UserTypes choicelist.

Examples of such user types modules are lino.core.user_types and lino_noi.lib.noi.user_types.