pyvelm v0.17.0¶
Release date: 2026-05-27
A bundled file library + file picker for ir.attachment,
plus a generic image=<field> slot on kanban cards so any model can
get a thumbnail view for free.
Highlights¶
file_manager module¶
A small bundled app that turns the existing ir.attachment table
into a browsable library:
| Where | What |
|---|---|
| Files → Library | Thumbnail kanban — image MIMEs render their bytes; everything else gets a MIME-icon tile |
| Files → All files | Sortable list (name, MIME, size, owning record, public, uploaded-at). + New jumps to the upload page |
GET/POST /web/files/upload |
Multipart upload page — pick one or many, optional Public flag, redirects back to the library |
GET /web/files/picker?accept=&q=&multi=0\|1 |
Picker dialog body (live search, MIME filter, inline upload) |
POST /web/files/picker/upload |
Upload-from-dialog (returns the new row JSON so the picker selects it) |
Install hook grants:
- Admin — full CRUD on
ir.attachment. - User — read on
ir.attachment(so non-admins can pick files via the widgets even when they can't reach the management UI).
File-picker widgets¶
Two new widgets sit on the existing Many2one / Many2many machinery:
class Brochure(BaseModel):
_name = "marketing.brochure"
title = Char(required=True)
cover_id = Many2one("ir.attachment")
asset_ids = Many2many("ir.attachment")
field("cover_id", widget="file", accept="image/*")
field("asset_ids", widget="files", accept="application/pdf,image/*")
- Edit mode: chip list of selections + Pick a file button. The
button opens
PvDialogagainst/web/files/picker; the dialog shows the library as a thumbnail grid, with a live name search and an inline upload that auto-selects the newly created row. - Display mode: image MIMEs render as a clickable thumbnail; other MIMEs render as a small file pill with a download link.
- The
accept=token flows into both the library query (mimetype ilike) and the upload input'sacceptattribute, so operators only see files they can pick.
Single-mode picks close the dialog on tile click. Multi-mode picks
collect a selection and emit it via the Use selected footer
button. The dialog's onResult patches the field's hidden input —
Many2one stores one id; Many2many stores comma-separated ids (the
existing parent-form parser already accepts both shapes).
Generic image slot on kanban cards¶
card(...) gained an image=<field> keyword. The renderer pulls
the field's string value (a URL) into card["image_url"]; the card
template renders a 4:3 thumbnail above the title when non-empty.
kanban_view(
"file_manager.file.kanban", "ir.attachment",
card=card("name", image="thumbnail_url", subtitle="mimetype"),
)
file_manager extends ir.attachment with a computed
thumbnail_url Char that returns
/api/attachment/{id}/download for image MIMEs, the external url
for URL-typed image attachments, and "" otherwise. Reuse the slot
in your own kanbans by exposing any Char field that resolves to a URL.
Upgrade¶
- Apps → Install
file_manager— depends onbase+admin; no base schema bumps. - Hard-refresh the browser so the updated kanban card template loads and the new widget JS runs.
- To use the picker on existing models, declare
Many2one("ir.attachment")/Many2many("ir.attachment")fields and reference them asfield(..., widget="file"|"files", accept="...")in your view arch.
Also in this release¶
card(...)builder docstring +ArchKanbanCardTypedDict gain theimagekey._kanban_cards_for_records()accepts animage_attr=kwarg; the card template renders the thumbnail block conditionally oncard.image_url.- New tests in
pyvelm/tests/test_file_manager.pycover the kanban image slot, picker dialog rendering (with / without upload, empty state), and the field-side template's seeded chips.