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