How to Implement with_user() vs sudo() in Odoo?
Overview
In Odoo, methods like with_user() and sudo() are used to change the execution context’s user when accessing or modifying records. However, their behavior and purpose differ significantly.
✅ sudo(): Superuser Access
Purpose
- Executes operations as Superuser (Admin – UID 1)
- Bypasses record rules and access rights
- Used to forcefully read/write data, regardless of user permissions
Syntax
record = self.env[‘res.partner’].sudo().browse(partner_id)
Use Case
Update sensitive data regardless of user rights:
self.sudo().write({‘is_company’: True})
✅ Bypasses security. Use cautiously.
✅ with_user(user_id) : Change Current User Context
Purpose
- Executes with a specific user’s rights
- Respects record rules and access rights of the provided user
- Useful for testing, simulating, or delegating as another user
Syntax
user = self.env.ref(‘base.user_demo’)
self.with_user(user).do_something()
Use Case
Trigger a method as a portal user with limited rights:
user = self.env.ref(‘base.public_user’)
self.with_user(user).action_confirm()
✅ Maintains real access control logic
🧠 Realistic Use Case in Odoo
Example: Writing a field
# Will ignore access rights
self.sudo().write({‘state’: ‘done’})
# Will check access rules of specified user
user = self.env.ref(‘base.user_admin’)
self.with_user(user).write({‘state’: ‘done’})
⚠️ Key Differences
Feature |
sudo() |
with_user() |
| User used | Superuser (UID 1) | Custom user |
| Respects record rules | ❌ No | ✅ Yes |
| Respects access rights | ❌ No | ✅ Yes |
| Security risk | High (bypasses everything) | Low (uses real user) |
| Use for impersonation | 🚫 No | ✅ Yes |
| Use for forced writes | ✅ Yes | 🚫 Only if user has rights |
✅ When to Use
Situation |
Recommended Method |
| Need to bypass permissions | sudo() |
| Simulate behavior of another user | with_user() |
| Trigger logic with accurate access | with_user() |
| System update from background task | sudo() |