Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More

courses : Managing courses

The courses plugin adds functionality for managing “activities”.

The internal name “courses” is for historic reasons. We should one day rename the plugin to “activities”. We didn’t yet do this because we are so used with the old name and because a rename will require extra attention with database migrations.

See also The courses plugin. See also Activities in Lino Voga, Activities in Lino Avanti, Therapies and Lino Welfare.

Lines starting with >>> in this document are code snippets that get tested as part of our development workflow.

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

Plugin configuration

The activity leader can be any database model. This is configured in Plugin.teacher_model, for which the default value is contacts.Person.

The participants of an activity can be any database model. This is configured in Plugin.pupil_model, for which the default value is contacts.Person.

The Course model

class lino_xl.lib.courses.Course

Django database model to represent an activity.

Database fields:


Don’t generate meeting having their start date beyond this date.


Until when new enrolments are accepted.


Available places. The maximum number of participants to allow in this activity.


Number of free places.


Number of requested places.


Number of trying places.


Number of confirmed places.

Inherited database fields: RecurrenceSet.start_date RecurrenceSet. RecurrenceSet.positions RecurrenceSet.every RecurrenceSet.every_unit

get_detail_action(self, ar)

Custom get_detail_action because the detail_layout to use depends on the activity layout, which is given by the Line.course_area field of the activity’s line.

class lino_xl.lib.courses.Courses

Base table for all activities.

Filter parameters:


Whether to show or to hide courses in an exposed state.

That is, all courses in a state that has CourseState.is_exposed set to True.

This parameter is ignored if the state parameter is also specified.

class lino_xl.lib.courses.MyActivities

Show the courses authored by me (i.e. where I am the responsible manager). Compare MyCoursesGiven.

class lino_xl.lib.courses.MyCoursesGiven

Show the courses given by me (i.e. where I am the teacher). Compare MyActivities.

This requires the partner field in my user settings to point to me as a teacher.

For users whose partner field is empty, this list shows all courses without teacher.

class lino_xl.lib.courses.ActivitiesByLine

Show the courses per course line.

class lino_xl.lib.courses.ActivitiesByTopic

Shows the courses of a given topic.

The Enrolment model

class lino_xl.lib.courses.Enrolment

Django database model to represent an activity enrolment.


One of lino_xl.lib.courses.EnrolmentStates.


Virtual HtmlBox field showing the name and address of the participant.

class lino_xl.lib.courses.Enrolments

Base class for all tables that show Enrolment.

class lino_xl.lib.courses.AllEnrolments

Show global list of all enrolments.

class lino_xl.lib.courses.PendingRequestedEnrolments

Show all requested enrolments.

class lino_xl.lib.courses.PendingConfirmedEnrolments

Show all confirmed enrolments.

class lino_xl.lib.courses.EnrolmentsByPupil

Show all enrolments of a given pupil.

class lino_xl.lib.courses.EnrolmentsByCourse

Show the enrolments of a course.

Enrolment workflow

The state of an enrolment can be one of the following:

>>> rt.show('courses.EnrolmentStates')
======= =========== =========== ============= ============= ==============
 value   name        text        Button text   invoiceable   Uses a place
------- ----------- ----------- ------------- ------------- --------------
 10      requested   Requested                 No            No
 11      trying      Trying                    No            Yes
 20      confirmed   Confirmed                 Yes           Yes
 30      cancelled   Cancelled                 No            No
======= =========== =========== ============= ============= ==============
class lino_xl.lib.courses.EnrolmentStates

The list of possible states of an enrolment.

The default implementation has the following values:


The enrolment was cancelled before it even started.


The enrolment was was successfully ended.


The enrolment was abandoned.

The Slot model

class lino_xl.lib.courses.Slot

The Line model

class lino_xl.lib.courses.Line

Django database model to represent an activity line.


The designation of this activity line as seen by the user e.g. when selecting the line.

One field for every language.


The text to print as title in enrolments.

See also lino_xl.lib.excerpts.mixins.ExcerptTitle.excerpt_title.


The body template to use when printing an activity of this line. Leave empty to use the site’s default (defined by body_template on the lino_xl.lib.excerpts.models.ExcerptType for Course)


Pointer to ActivityLayouts. This is used only when an application defines several variants of EnrolmentsByPupil.

Activity layouts

The ActivityLayouts choicelist is where the application developer can define the available activity layouts.

The default configuration contains only one choice:

>>> rt.show(courses.ActivityLayouts)
======= ========= ============ ============================
 value   name      text         Table
------- --------- ------------ ----------------------------
 C       default   Activities   courses.ActivitiesByLayout
======= ========= ============ ============================

Usage examples see Activities in Lino Voga and Therapies.

The layout of an activity can customize how data fields and related data are to be laid out on screen. This is done by defining a subclass of ActivitiesByLayout and referring to it in the ActivityLayout.courses_table.

class lino_xl.lib.courses.ActivityLayouts

The global choicelist of activity layouts. Every choice is an instance of ActivityLayout.

class lino_xl.lib.courses.ActivityLayout

The translatable designation used as menu label.


Which table to use for showing activities having this layout.

The state of an activity

>>> rt.show(courses.CourseStates)
======= ========== ========== ========= ========== ============= =================
 value   name       text       Exposed   Editable   Invoiceable   Update calendar
------- ---------- ---------- --------- ---------- ------------- -----------------
 10      draft      Draft      Yes       Yes        No            No
 20      active     Started    Yes       No         Yes           No
 30      inactive   Inactive   No        No         No            No
 40      closed     Closed     No        No         No            No
======= ========== ========== ========= ========== ============= =================
class lino_xl.lib.courses.CourseStates

Every course state has itself some additional attributes that are used to group them at certain places.

class lino_xl.lib.courses.CourseState

For example you can retrieve a list of course states that are to be considered “exposed” (Courses.show_exposed):

>>> courses.CourseStates.filter(is_exposed=True)
[<courses.CourseStates.draft:10>, <courses.CourseStates.active:20>]
>>> courses.CourseStates.filter(is_exposed=False)
[<courses.CourseStates.inactive:30>, <courses.CourseStates.closed:40>]

As an application developer you can redefine the items of CourseStates in order to adapt it to the needs of your application.

TODO: Write a tutorial about redefining choicelists.


class lino_xl.lib.courses.ConfirmAllEnrolments

Plugin configuration

class lino_xl.lib.courses.Plugin
teacher_model = 'contacts.Person'
pupil_model = 'contacts.Person'
pupil_name_fields = "pupil__name"

The value to use as quick_search_fields for Enrolment.

Note that this remains a text string while quick_search_fields is resolved into a tuple of data elements at site startup.

Presence sheet

The presence sheet of a course is a printable document For example Presence sheet.


The template used for printing a presence sheet of an activity (both versions pdf and html)