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 Comparison 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() |