8000 chapter 5 - connect the dots · odoo/documentation@9fbf595 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9fbf595

Browse files
committed
chapter 5 - connect the dots
1 parent 80dd3d5 commit 9fbf595

File tree

5 files changed

+208
-42
lines changed

5 files changed

+208
-42
lines changed

content/developer/tutorials/server_framework_101.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Ready? Let's get started!
3939
- :doc:`server_framework_101/02_lay_the_foundations`
4040
- :doc:`server_framework_101/03_build_user_interface`
4141
- :doc:`server_framework_101/04_relational_fields`
42-
- :doc:`server_framework_101/05_business_logic`
42+
- :doc:`server_framework_101/05_connect_the_dots`
4343
- :doc:`server_framework_101/06_security`
4444
- :doc:`server_framework_101/07_advanced_views`
4545
- :doc:`server_framework_101/08_inheritance`

content/developer/tutorials/server_framework_101/05_business_logic.rst

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
===========================
2+
Chapter 5: Connect the dots
3+
===========================
4+
5+
In this chapter, we'll add business logic to the models to automate the processes of our application
6+
and turn it into a dynamic and useful tool. This will involve defining actions, constraints,
7+
automatic computations, and other model methods.
8+
9+
.. todo: explain the env (self.env.uid, self.env.user, self.env.ref(xml_id), self.env[model_name])
10+
.. todo: explain magic commands
11+
.. todo: 6,0,0 to associate tags to properties in data
12+
.. todo: create (create offer -> offer received state) and write methods
13+
.. todo: auto-update property state based on received offers state (write)
14+
.. todo: best offer stat button
15+
.. todo: accepting offer refuses others
16+
17+
.. _tutorials/server_framework_101/computed_fields:
18+
19+
Computed fields
20+
===============
21+
22+
.. todo: change section title
23+
24+
**Computed fields** are a special type of field that derive their value through programmatic
25+
computation rather than direct storage. The computation is performed on-the-fly by the server
26+
whenever the field is accessed. This makes computed fields highly convenient for tasks like
27+
displaying the results of calculations directly in views, automating repetitive processes, or
28+
assisting users with data entry.
29+
30+
In Odoo, computed fields are implemented by defining a specific Python method and linking it to a
31+
field declaration using the `compute` argument. This method operates on a **recordset** :dfn:`a
32+
collection of records from the same model` represented by the `self` argument of the compute method.
33+
The method must iterate over the records to compute and set the field's value. When the computation
34+
depends on other fields, the method is decorated with :code:`@api.depends()`, which specifies the
35+
fields that should trigger an automatic recomputation whenever their value changes.
36+
37+
.. todo: ref on recordsets
38+
.. todo: compute (offer deadline)
39+
.. todo: For relational fields, it’s possible to use paths through a field as a dependency: @api.depends('partner_id.name')
40+
.. todo: methods are private by default, meaning that they can't be called from the presentation
41+
tier, only from the business tier. See chap 1
42+
.. todo: Although relational field names end with the `_id` or `_ids` suffix, variables holding a recordset of such fields
43+
are typically not suffixed. That is because, while the field represents the referenced record's id that is stored in the
44+
database, the variable is holding the full record in memory.
45+
46+
.. _tutorials/server_framework_101/inverse_computed_fields:
47+
48+
Inverse computed fields
49+
-----------------------
50+
51+
You might have noticed that computed fields are read-only by default. This is expected since the
52+
user is not supposed to set a value by themselves.
53+
54+
.. todo: change section title
55+
56+
tmp
57+
58+
.. todo: inverse (offer deadline)
59+
60+
.. _tutorials/server_framework_101/related_fields:
61+
62+
Related fields
63+
--------------
64+
65+
.. todo: change section title
66+
67+
tmp
68+
69+
.. todo: related fields (buyer's phone)
70+
71+
.. _tutorials/server_framework_101/stored_computed_fields:
72+
73+
Stored computed fields
74+
----------------------
75+
76+
.. todo: change section title
77+
78+
tmp
79+
80+
.. todo: implement search method
81+
.. todo: api.depends triggers a recomputation when update (already said above)
82+
83+
.. _tutorials/server_framework_101/onchanges:
84+
85+
Onchange methods
86+
================
87+
88+
.. todo: change section title
89+
90+
**Onchange methods** are a feature of the server framework designed to respond to changes in field
91+
values directly within the user interface. They execute when a user modifies a field in a form view,
92+
even before saving the record to the database. This allows for real-time updates of other fields and
93+
provides immediate user feedback, such as validations, warnings, or suggestions. However, because
94+
onchange methods are only triggered by changes made in the UI, specifically from a form view, they
95+
are best suited for assisting with data entry and providing feedback, rather than implementing core
96+
business logic in a module.
97+
98+
In Odoo, onchange methods are implemented as Python methods and linked to one or more fields using
99+
the :code:`@api.onchange()` decorator. These methods are triggered the specified fields' values are
100+
altered and operate on the in-memory representation of a single-record recordset received through
101+
`self`. If field values are modified, the changes are automatically reflected in the UI.
102+
Additionally, onchange methods can return non-blocking warnings or raise blocking errors to guide
103+
users during data entry.
104+
105+
106+
.. todo: raise UserError + translation
107+
.. todo: if garden checked -> show and compute total area
108+
109+
tmp
110+
111+
.. _tutorials/server_framework_101/constraints:
112+
113+
Constraints
114+
===========
115+
116+
.. todo: change section title
117+
118+
tmp
119+
120+
.. _tutorials/server_framework_101/sql_constraints:
121+
122+
SQL constraints
123+
---------------
124+
125+
tmp
126+
127+
.. todo: price more than zero
128+
.. todo: unique tag constraint
129+
130+
.. _tutorials/server_framework_101/python_constraints:
131+
132+
Python constraints
133+
------------------
134+
135+
tmp
136+
137+
.. todo: accept only one offer
138+
139+
.. _tutorials/server_framework_101/defaults:
140+
141+
Defaults
142+
========
143+
144+
.. todo: change section title
145+
.. todo: introduce lambda functions for defaults :point_down:
146+
also mention that `self` is evaluated as the current recordset in lambda functions
147+
148+
There is a problem with the way we defined our `Date` fields in the previous chapters: their default value relies on
149+
:code:`fields.Date.today()` or some other static method. When the code is loaded into memory, the date is
150+
computed once and reused for all newly created records until the server is shut down. You probably didn't
151+
notice it, unless you kept your server running for several days, but it would be much more visible with
152+
`Datetime` fields, as all newly created records would share the same timestamp.
153+
154+
That's where lambda functions come in handy. As they generate an anonymous function each time they're evaluated
155+
at runtime, they can be used in the computation of default field values to return an updated value for each new record.
156+
157+
.. todo: salesperson_id = fields.Many2one(default=lambda self: self.env.user)
158+
.. todo: real.estate.offer.amount::default -> property.selling_price (add related?)
159+
.. todo: real.estate.tag.color -> default=_default_color ; def _default_color(self): return random.randint(1, 11) (check if lambda works)
160+
.. todo: copy=False on some fields
161+
162+
.. _tutorials/server_framework_101/actions:
163+
164+
Actions
165+
=======
166+
167+
.. todo: change section title
168+
.. todo: "assign myself as salesperson" action
169+
.. todo: "view best offer" statbutton
170+
.. todo: accept/refuse offer buttons
171+
.. todo: action name=...
172+
173+
tmp
174+
175+
.. _tutorials/server_framework_101/action_object:
176+
177+
Object
178+
------
179+
180+
tmp
181+
182+
.. _tutorials/server_framework_101/action_name:
183+
184+
Name
185+
----
186+
187+
tmp
188+
189+
.. _tutorials/server_framework_101/shell:
190+
191+
Shell
192+
=====
193+
194+
.. todo: change section title
195+
196+
tmp
197+
198+
----
199+
200+
.. todo: add incentive for chapter 6

content/developer/tutorials/server_framework_101/07_advanced_views.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ Chapter 7: Advanced views
44

55
tmp
66

7-
.. todo:: invisible, required, readonly modifiers
8-
.. todo:: introduce bootstrap
9-
.. todo:: widgets; eg, <widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active"/>
10-
.. todo:: add Gantt view of properties availability
11-
.. todo:: add Kanban view of properties
7+
.. todo: invisible, required, readonly modifiers
8+
.. todo: introduce bootstrap
9+
.. todo: widgets; eg, <widget name="web_ribbon" title="Archived" bg_color="text-bg-danger" invisible="active"/>
10+
.. todo: add Gantt view of properties availability
11+
.. todo: add Kanban view of properties
1212
1313
----
1414

content/developer/tutorials/server_framework_101/08_inheritance.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ Chapter 8: Inheritance
44

55
tmp
66

7-
.. todo:: inherit from mail.tread mixin and add a chatter
7+
.. todo: inherit from mail.tread mixin and add a chatter
8+
.. todo: self.env._context
89
910
----
1011

0 commit comments

Comments
 (0)
0