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

uploads : Managing uploaded files

The lino.modlib.uploads plugin adds functionality for managing “uploads”. This includes the upload action as such, but also processing the uploaded files, such as linking them to other database content, monitoring their validity.

This plugin holds just the minimal core functionality. Most applications use its extension, the lino_xl.lib.uploads plugin, which is described in Uploads with expiration date management.

This document contains code snippets (lines starting with >>>) that get tested as part of our development workflow.

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


upload type

The type of an upload file.

upload area

A group of upload types that are being displayed in a given upload panel.

Upload files

class lino.modlib.uploads.Upload

Django model representing an upload file.


Pointer to the uploaded file itself (a Django FileField).


The size of the file in bytes. Not yet implemented.


The media type of the uploaded file.

See also this thread about length of MIME type field.


The type of this upload.

Pointer to UploadType. The choices for this field are usually limited to those in the same upload area.


A short description entered manually by the user.


A pointer to the library volume where this file is stored.


The upload area this file belongs to.


The path of this file, relative the volume’s root.

Almost the same as description, but if file is not empty, the text is clickable, and clicking on it opens the uploaded file in a new browser window.

class lino.modlib.uploads.Uploads

Base class for all data tables of upload files.

class lino.modlib.uploads.AllUploads

Shows all upload files on this Lino site.

Visible to the end user as Explorer ‣ Office ‣ Upload files.

>>> rt.show(uploads.AllUploads, language="en")
================================= ================= ================= ===================== ============= ====
 File                              Upload type       Uploaded by       Controlled by         Description   ID
--------------------------------- ----------------- ----------------- --------------------- ------------- ----
 uploads/2015/03/PRC_21_2015.pdf   Source document   Robin Rood        `PRC 21/2015 <…>`__                 7
 uploads/2015/03/PRC_20_2015.pdf   Source document   Rolf Rompen       `PRC 20/2015 <…>`__                 6
 uploads/2015/03/PRC_19_2015.pdf   Source document   Romain Raffault   `PRC 19/2015 <…>`__                 5
 uploads/2015/03/PRC_18_2015.pdf   Source document   Robin Rood        `PRC 18/2015 <…>`__                 4
 uploads/2015/03/PRC_17_2015.pdf   Source document   Rolf Rompen       `PRC 17/2015 <…>`__                 3
 uploads/2015/03/PRC_16_2015.pdf   Source document   Romain Raffault   `PRC 16/2015 <…>`__                 2
 uploads/2015/03/PRC_15_2015.pdf   Source document   Robin Rood        `PRC 15/2015 <…>`__                 1
================================= ================= ================= ===================== ============= ====
class lino.modlib.uploads.AreaUploads

Mixin for tables of upload files where the upload area is known.

The summary displays the upload files as a list grouped by uploads type.

This is inherited by UploadsByController.

This also works on lino_welfare.modlib.uploads.UploadsByProject and their subclasses for the different _upload_area.

class lino.modlib.uploads.MyUploads

Shows my uploads (i.e. those whose author is the requesting user).

class lino.modlib.uploads.UploadBase

Abstract base class of Upload. This was named lino.mixins.uploadable.Uploadable until 20210217. It encapsulates some really basic functionality. Its usage is deprecated. If you were inheriting from lino.mixins.Uploadable, you should convert that model to point to an Upload instead.

Upload areas

The application developer can define upload areas. Every upload area has its list of upload types. The default has only one upload area.

>>> rt.show(uploads.UploadAreas, language="en")
======= ========= =========
 value   name      text
------- --------- ---------
 90      general   Uploads
======= ========= =========

For example Lino Welfare extends this list.

Upload types

class lino.modlib.uploads.UploadType

Django model representing an upload type.


Optional pointer to a virtual upload shortcut field. If this is not empty, then the given shortcut field will manage uploads of this type. See also Shortcuts.

class lino.modlib.uploads.UploadTypes

The table with all existing upload types.

This usually is accessible via the Configure menu.

Upload controllers

An upload file is usually associated (linked) to a another database object called its controller. Upload files without a controller are considered “useless”, and the site manager should decide what to do with them.

upload controller

Any database object that can potentially have uploaded files associated to it.

Any database model that inherits from UploadController.

class lino.modlib.uploads.UploadController

Model mixin for database objects that can have upload files associated to them.

Turns a model into an upload controller.


Opens a data window with the uploaded files associated to this database object.

This action is automatically shown in the toolbar as a button.

Additionally to UploadController.show_uploads, the application developer can decide to add a slave panel UploadsByController to the detail layout of any upload controller.

class lino.modlib.uploads.UploadsByController

Shows the uploaded files associated to this database object.

This panel gives a summary of the upload files linked to this database row. This summary is influenced by the configuration of upload types.

>>> obj = vat.VatAccountInvoice.objects.get(id=105)
>>> rt.show(uploads.UploadsByController, obj)
Source document: `PRC_21_2015.pdf <…>`__ `⇲ </media/uploads/2015/03/PRC_21_2015.pdf>`__ / `❏ <javascript:window.App.runAction({ "actorId": "vat.Invoices", "an": "show_uploads", "onMain": false, "rp": null, "sr": 105, "status": {  } })>`__

Upload shortcuts

The application developer can define upload shortcuts. Every upload shortcut will create an upload shortcut field, a virtual field with a set of actions for quickly uploading or viewing uploads of a particular type for a given database object.


  • Declare your Site’s upload shortcuts from within your workflows_module. For example:

    from lino.modlib.uploads.choicelists import add_shortcut as add
    add('contacts.Person', 'uploaded_foos', _("Foos"))
  • Make the uploaded_foos field visible in some detail layout.

  • Using the web interface, select Configure ‣ Office ‣ Upload types, create an upload type named “Foo” and set its shortcut field to “Foos”.

  • Upload a file from your PC to the server.

  • Open the uploaded file in a new browser window

class lino.modlib.uploads.Shortcuts

The list of available upload shortcut fields in this application.

>>> rt.show(uploads.Shortcuts, language="en")
No data to display
lino.modlib.uploads.add_shortcut(*args, **kw)

Declare an upload shortcut field. This is designed to be called from within your workflows_module.


A directory below your media directory. This is where web uploads (i.e. files uploaded via the web interface) are stored. Lino creates this directory at startup if it doesn’t exist.

Data checkers

This plugin defines two data checkers:

class lino.modlib.uploads.UploadChecker
class lino.modlib.uploads.UploadsFolderChecker

Find orphaned files in uploads folder.

Walks through the uploads folder and reports files for which there is no upload entry