6. Domains, PYSON, and security
Objectives
- read and compose domains
- use PYSON for client states
- separate usability restrictions from access rules
Mental model
A domain describes candidate records or a search. PYSON makes declarations depend on record/context values. Access rights and record rules remain the security boundary.
Guided practice
- Write the business restriction in plain language.
- Translate it into a domain and test representative records.
- Use Eval and Bool only for client presentation.
- Add model access and record rules for authorization.
- Test direct model calls with allowed and denied users.
Minimal example
from trytond.model import fields
from trytond.pyson import Eval
author = fields.Many2One(
'library.author', "Author",
domain=[('active', '=', True)],
states={
'readonly': Eval('state') != 'draft',
'required': Eval('state') == 'draft',
},
depends=['state'])
# Search examples
Book.search([('author.name', 'ilike', 'Ada%')])
Book.search(['OR', ('price', '=', None), ('price', '>=', 0)])
How to read the example
Domains can traverse Many2One relations. Keep them understandable: deeply nested expressions should be named, documented, and covered by truth-table tests.
Exercise
Restrict authors by company and active status, then prove a forged context cannot read another company’s protected records.
Run the exercise first with a minimal valid case, then add an invalid case and turn both into repeatable tests.
Verifiable result
The chooser is helpful in the client and the server independently rejects unauthorized access.
Common mistakes
- using states or domains as authorization
- forgetting null cases
- depending on a field not declared in depends
- building domains from untrusted strings
Ready-to-advance criteria
- I can explain the concepts without looking at the code.
- Valid and invalid cases have tests.
- I tested with a non-administrative user.
- I know how to upgrade and restore the training database.
Version and references
Series 8.0 requires at least Python 3.10 according to official metadata. The official server declares its project with pyproject.toml; new modules should use modern packaging and verify wheel contents. Do not confuse this historical minimum with the Python version certified by your organization.
This edition pins examples and dependencies to series 8.0. Check the official 8.0 tutorial, server API, and source branch before moving a pattern to production.