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