Skip to main content
iVentureTeam

many2many_binary

Several files on one record, uploaded in one go: the many2many_binary widget turns a many2many to ir.attachment into Odoo's multi file upload zone.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 12, 2026Updated August 12, 20266 min read
Odoo 19 form view showing the many2many_binary widget with several uploaded attachments as cards, image thumbnails and file type icons, plus the attach button.
Technical namemany2many_binary
Field typesmany2many
Viewsform
Moduleweb, present in every Odoo database
Used in core13 occurrences across 10 modules, including mail, hr_recruitment, pos_self_order, mail_group, survey, hr_holidays
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0
No-code setupNo. Studio's Many2Many widgets are Checkboxes and Tags; this widget plus its ir.attachment relation are set up in XML.
Alternativesbinary, image, one2many, many2many_tags

What the Attachments field does

Where the binary widget stores one file in a column, this widget manages a pile: supporting documents on a leave request, attachments on a recruitment application, files on a mail group message. Each file is a real ir.attachment record, and the field is a many2many linking the record to its attachments. The widget renders each linked file as a card with its name, extension badge and a delete cross, image files get a real thumbnail, and an attach button opens a multi select file picker so a user can drop five PDFs in one action.

Uploads go through Odoo's standard attachment upload controller, and each returned attachment id is linked to the field one by one. A failed file surfaces a danger notification with the upload error while the rest continue.

What this means for your team

The choice this widget forces is healthy: files become first class attachment records with their own access rules, storage handling and lifecycle, instead of blobs buried in a table column. That is what you want for anything users accumulate over a record's life, evidence on an expense, submissions on an application, signed annexes on an agreement.

Two operational notes from implementations. First, deletion here unlinks with one click and no confirmation dialog, so for compliance sensitive documents pair the field with archive style processes rather than trusting the UI to protect files. Second, because each upload is a real attachment, storage governance, filestore location, size discipline, cleanup of orphaned attachments, becomes an administration topic the moment this widget ships to a busy team. Both are process decisions, not widget settings, and they are cheaper to make before go live.

Supported options in Odoo 19

Verified against many2many_binary_field.js in the Odoo 19.0 web module: two options, both honest, plus behavior facts that live in the template rather than the options table.

OptionTypeWhat it does
accepted_file_extensionsstringComma separated extension list passed to the file picker's accept filter, like '.pdf,.docx'. A picker convenience only; nothing re-validates what users force through with All Files.
number_of_filesintegerHides the attach button once the number of linked files reaches this value. Existing extras remain untouched, and API writes ignore the cap. Unset means unlimited.

number_of_files is a soft cap. The template hides the attach button once the linked count reaches the limit; it never deletes or blocks existing records above it, and records arriving through code or imports bypass it entirely. Treat it as UI guidance, and enforce hard limits server side when they matter.

Working examples

Standard multi file attachments

<field name="attachment_ids" widget="many2many_binary"/>

The model side: the relation must target ir.attachment

attachment_ids = fields.Many2many(
    "ir.attachment",
    string="Supporting Documents",
)

The field label doubles as the upload button caption, so name it the way the button should read.

PDF only, capped at three files

<field name="attachment_ids"
       widget="many2many_binary"
       options="{'accepted_file_extensions': '.pdf', 'number_of_files': 3}"/>

The attachment pipeline behind the cards

Why ir.attachment is not optional. The widget's upload path posts to /web/binary/upload_attachment, the controller that creates attachment records, then links each returned id into the field. Its card rendering depends on name and mimetype, which the widget declares as related fields so they load automatically, and downloads go through /web/content/<id>?download=true, an attachment route. Point the many2many at any other model and every one of those steps has nothing to work with.

How the cards decide their look. A file whose mimetype starts with image/ renders an actual thumbnail through /web/image, with a generic image icon as the error fallback; everything else gets Odoo's mimetype icon plus an uppercase extension badge derived from the file name. The image detection helper only entered the component in 19.0, one of the two functional differences from 18.

What readonly hides. In readonly mode the template drops the attach button and the per card delete crosses, leaving a clean gallery of downloadable files, which makes the widget perfectly usable on portal style read only forms.

What is not there. No drag and drop target, despite the multi select picker, no confirmation on delete, and no one2many support: supportedTypes declares many2many alone. Attachment lists needing per row metadata columns belong in an embedded one2many list on a model that wraps the attachment instead.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. No functional change visible on the development branch. Details below.
Odoo 19.0VerifiedVerified against the shipped source. Image attachments gain inline thumbnails.
Odoo 18.0VerifiedSame options and upload flow. No image detection, so all files rendered with mimetype icons.

Upgrade note for 18 to 19. Views carry over untouched. The visible gain is image thumbnails: 18's component had no image detection, so every file rendered with the generic mimetype icon, while 19 previews image attachments inline. Options are identical across the two versions.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. The statements below are read from the public development branch, which is unstable until feature freeze, and the page is re-verified once the release ships.

No functional changes are visible for this widget. The diff against 19.0 is a mechanical migration of the props declaration to the new schema system and a refactor of the file mapping code, with options, supported types, upload flow and template behavior unchanged. Both options survive with the same names.

That makes many2many_binary one of the stable corners of the upgrade: plan around the fields that do change, and let this one ride along. An Odoo migration assessment sorts your views into exactly those two piles.

Common problems and fixes

SymptomCause and fix
Uploads fail or nothing links to the recordThe many2many does not target ir.attachment, so the upload controller's records cannot be linked. Point the field at ir.attachment; wrap attachments in a child model only when you need extra columns.
The attach button disappearednumber_of_files was reached, or the field is readonly on this record. Raise or drop the cap, or check the readonly modifier.
Upload button carries a strange captionThe caption is the field's label string. Rename the field label to what the button should say.
A file was deleted with one click and no warningThe delete cross unlinks immediately; the widget has no confirmation dialog. Expected. Restrict deletion rights or handle retention server side for sensitive documents.
No image previews, only generic iconsOn 18 that is the only rendering; on 19 the attachment's mimetype is not image/ prefixed, often from files uploaded with a wrong type. Upgrade, or fix the stored mimetype on the attachment.
Widget errors on a one2many fieldsupportedTypes is many2many only. Use a many2many to ir.attachment, or an embedded one2many list on a wrapper model.

Attachments field vs the alternatives

WidgetBest forKey difference
many2many_binarySeveral loose files accumulated on one recordMulti upload into real ir.attachment records
binaryExactly one file with a fixed meaningSingle column storage, no attachment records
imageOne picture displayed on the recordInline image rendering with resized variants
one2manyFiles needing per file metadata columnsEmbedded list on a wrapper model, columns included
many2many_tagsLinking existing records rather than uploadingPill selection UI, no upload path

Decide by cardinality and metadata: one known file wants binary, many loose files want this widget, and many files with structured per file data, types, expiry dates, review states, want a real child model with an embedded list.

Frequently asked questions

How do I let users upload multiple files on one Odoo record?+
Add a many2many field targeting ir.attachment and render it with widget="many2many_binary". The attach button accepts multiple files in one picker session, and each becomes an attachment record linked to the field.
Does many2many_binary require ir.attachment?+
Yes. Uploads post to the attachment controller, cards read attachment fields like name and mimetype, and downloads use attachment routes. A many2many to any other model leaves the widget nothing to work with.
How do I limit how many files can be attached?+
Set options="{'number_of_files': 3}". The attach button hides once three files are linked. It is a UI cap only: existing extras stay, and imports or API writes are not blocked, so mirror hard limits in a server constraint.
Can I restrict uploads to certain file types?+
The accepted_file_extensions option pre-filters the picker, for example '.pdf,.png'. Like all picker filters it is advisory, so pair it with server side checks when the restriction is a rule rather than a convenience.
Why does the upload button say the field name?+
By design: the widget uses the field's label as the button caption. Label the field 'Attach Supporting Documents' and that is exactly what the button reads.
Do image attachments show previews?+
Since Odoo 19, yes: files whose mimetype starts with image/ render as thumbnails, with other types showing mimetype icons and an extension badge. Odoo 18 had no image detection in this widget at all.
Is there a Studio way to add this widget?+
No. Studio offers Checkboxes and Tags for many2many fields, not the attachment uploader, so the field and widget are declared in XML. It is a two line change on an existing model.
Does many2many_binary change in Odoo 20?+
The development branch shows only internal refactoring, with options and behavior unchanged, making this one of the stable widgets for the upgrade. We re-verify against the final release in late September 2026.

Attachment sprawl creeping into your workflows?

Multi file uploads are easy to add and hard to govern: storage grows, sensitive documents hide in odd corners, and nobody owns cleanup. We implement document handling on Odoo with the access rules, retention and filestore strategy worked out, so attachments stay an asset instead of a liability.

Book a free consultation

How this page was produced

Verified by reading many2many_binary_field.js and its QWeb template in the Odoo 19.0 web module, which is where the number_of_files gating and readonly behavior live, plus the FileInput component for the upload route. The file was diffed against 18.0, dating the image thumbnail behavior, and against the public development branch, which showed no functional change. Found an inaccuracy? Report it and we will correct the page.