# Tuesday, February 13, 2018¶

## Dashboard items and table titles¶

My yesterday’s changes caused a failure in Lino Welfare:

File "welfare/docs/specs/main.rst", line 49, in main.rst
Failed example:
for h in soup.find_all('h2'):
print(h.text.strip())
Expected:
Benutzer und ihre Klienten ⍐
Wartende Besucher ⍐
Meine Termine ⍐
Meine überfälligen Termine ⍐
Meine Benachrichtigungen ⍐
Got:
Benutzer und ihre Klienten ⍐
Wartende Besucher (Wartet) ⍐
Meine Termine (Verwaltet durch Rolf Rompen, Daten von 22.05.2014 bis ...) ⍐
Meine überfälligen Termine (Verwaltet durch Rolf Rompen, Daten von 01.04.2014 bis 22.05.2014) ⍐
Meine Benachrichtigungen (Empfänger Rolf Rompen, Nein) ⍐


Yes, indeed: lino.core.dashboard.DashboardItem.render_request() should not show the full title (get_title) buy just the get_title_base.

En passant:

• I changed the symbol used to show a dashboard item in own window from [⍐] (2350) to [⏏] (23CF)
• I added a new specs page The lino_xl.lib.events plugin (because I was surprised that abovementioned test failure appeared only during welfare, not already in book. With this page it would have appeared earlier.

## Lino Tera¶

I played with the names, labels, titles and references of courses, course lines, teams etc. I am fiddling around based on different (but fuzzy) input sources:

• feedback from Daniel after looking at the site
• the imported data I see on their production site
• what I believe they need

A team in lino_xl.lib.teams is now Referrable (which might require a database migration also for other applications).

Some translations. Verbose names and position in detail of fields Course.user and Course.teacher.

I changed the MyCoursesGiven no longer uses setup_request() and a master_key but simply param_defaults() (like in lino.modlib.users.My). This was needed after the changes in dashboard this morning.

## Django migrations in Lino¶

I started to think a bit more seriously about how Django migrations on a Lino application would look like. Because a restore.py at SPZ Eupen takes two hours. And because I saw how they work at ajapaik.

The fundamental challenge is that a Lino application can inject fields (i.e. one plugin causes a field to be created on a model in another plugin) and can have conditional fields (plugins whose database structure depends on some local setting). This challenge was easier than I feared, thanks to Django’s MIGRATION_MODULES setting: we define one common migrations module for all plugins of a given application. New site attribute lino.core.site.Site.migration_module. I tried this in lino_book.projects.min9. Seems to work as expected:

$go min9$ python manage.py makemigrations


It reveals two more challenges: choices and babel values. Django does not know how to serialize them. I must add a deconstruct() method for these. Seems feasible. To be tested.

Also the default value of ChoiceList fields causes a problem –at least in Python 2– because it uses an unbound method. In a first step I converted all default values in application code from the deprecated default=MyChoices.foo.as_callable form to default=MyChoices.as_callable(‘foo’). Just to discover that this is not enough because it also creates an unbound function. A possible solution could be to simply deserialize them to the choice’s value (which is a plain string) and to make a ChoiceListField interpret them correctly. If that works, we could define the default value of choicelist fields simply as default=’foo’. But will that work on choicelists that get repopulated in a custom_workflows module? We will see…