| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Lines of code | 217 |
| Technical Name |
direct_download_base |
| License | OPL-1 |
| Website | https://odoootips.com |
| Versions | 16.0 17.0 18.0 19.0 |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Lines of code | 217 |
| Technical Name |
direct_download_base |
| License | OPL-1 |
| Website | https://odoootips.com |
| Versions | 16.0 17.0 18.0 19.0 |
Odoo 18
CE + EE
Abstract Mixin
Direct Download Base
Download large reports (Excel, PDF, CSV) instantly. Files stream to the browser with zero database storage. Auto-cleanup on download.
1. Before vs After
Standard Odoo stores exports as ir.attachment records with base64 encoding. This module bypasses all of that.
| Aspect | Standard Odoo | Direct Download |
|---|---|---|
| RAM peak (15 MB Excel) | ~50 MB (BytesIO + base64 +33%) | ~15 MB (disk only) |
| RAM during download | ~15 MB (loads full file) | ~8 KB (streaming chunks) |
| Storage per export | +1 DB record + filestore (forever) | 0 (delete-on-download) |
| After 1 year (10 users, 5/day) | ~12,000 records, ~120 GB | 0 |
| Auto-cleanup | No (never) | Yes (download + autovacuum) |
| Security | Predictable attachment ID | Cryptographic token + TTL |
2. How It Works
|
💾
Write to DiskFile generated directly on disk via _DDOutputXlsx. No BytesIO, no RAM buffering.
|
📥
Stream 8 KBwrap_file() sends 8 KB at a time. Full file never in RAM during download.
|
🗑
Delete on Reados.unlink() before streaming. Linux unlink-while-open pattern.
|
⚙
Auto Vacuum@api.autovacuum cleans expired tokens + orphan files older than 2h.
|
3. For Developers
Step 1: Add dependency
"depends": ["direct_download_base"]
Step 2: Inherit the mixin
_inherit = ["direct.download.mixin"]
Step 3: Generate and download
# Excel: write directly to disk
dd = self.dd_output_xlsx("Report.xlsx")
wb = xlsxwriter.Workbook(dd)
...
wb.close()
return dd.action()
# PDF/CSV: from BytesIO or bytes
return self.dd_output_binary(output, "Report.pdf", "application/pdf")
dd = self.dd_output_xlsx("Report.xlsx")
wb = xlsxwriter.Workbook(dd)
...
wb.close()
return dd.action()
# PDF/CSV: from BytesIO or bytes
return self.dd_output_binary(output, "Report.pdf", "application/pdf")
| Method | Description |
|---|---|
dd_output_xlsx(filename) | Returns _DDOutputXlsx object. XlsxWriter writes to .part file, atomic rename on close, download action via .action() |
dd_output_binary(data, name, mime) | Accepts BytesIO or bytes. Writes to disk with shutil.copyfileobj() (1 MB chunks). Returns download action directly. |
4. Security
Every download is protected by a cryptographic one-shot token. No file is ever accessible without authentication.
| 🔒 Token | secrets.token_urlsafe(16) — 128 bits, cryptographically random, impossible to guess |
| 🔒 One-shot | Token invalidated after first download. Reusing the URL returns 404. |
| 🔒 TTL | Expires in 60 minutes by default (configurable). After expiry: 404. |
| 🔒 User check | create_uid == env.uid. Another user cannot download your file, even with the URL. |
| 🔒 Model check | Controller validates model inherits the mixin. Invalid model = 404, not 500. |
| 🔒 Path safety | No path traversal. token_urlsafe generates URL-safe chars only — no / or .. |
5. Requirements
| Odoo version | 16.0 Community or Enterprise |
| Server OS | Linux (unlink-while-open pattern requires Unix) |
| Dependency | Only web |
| Permissions | Odoo process needs write access to data_dir |
| File location | {data_dir}/direct_download/{dbname}/ |
| Cleanup | Automatic via Odoo's built-in @api.autovacuum cron |
Fields added to inheriting models:
dd_token, dd_relpath, dd_name, dd_mimetype, dd_expires_at — 5 lightweight columns, no extra table.
📧 Support & Guarantees
🛡
Quality Guaranteed
Battle-tested mixin used in production. If you find a bug, we fix it — no questions asked.
💬
Fast Response
We respond within 24 hours on business days. Most issues resolved within 48h.
🔄
Free Updates
Bug fixes and improvements published on Odoo Apps. Download anytime.
📞 Contact Us
🌐 Website
odootips.com
📝 When contacting support, please include:
- Odoo version (16.0.x.y.z)
- Module version
- Steps to reproduce
- Screenshots if applicable
Odoo Proprietary License v1.0 This software and associated files (the "Software") may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file). You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one). It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software. The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Please log in to comment on this module