~openerp-chinese-team/openobject-doc/Chinese-init

« back to all changes in this revision

Viewing changes to i18n/zh_CN/source/developer/03_modules_2.rst

  • Committer: JoshuaJan
  • Date: 2012-12-04 01:36:44 UTC
  • Revision ID: popkar77@gmail.com-20121204013644-k25kpyac672wxe22
Chinese initialization

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
.. i18n: Objects, Fields and Methods
 
3
.. i18n: ===========================
 
4
..
 
5
 
 
6
Objects, Fields and Methods
 
7
===========================
 
8
 
 
9
.. i18n: OpenERP Objects
 
10
.. i18n: ---------------
 
11
..
 
12
 
 
13
OpenERP Objects
 
14
---------------
 
15
 
 
16
.. i18n: .. This chapter is dedicated to detailed objects definition:
 
17
.. i18n:     all fields
 
18
.. i18n:     all objects
 
19
.. i18n:     inheritancies
 
20
..
 
21
 
 
22
.. This chapter is dedicated to detailed objects definition:
 
23
    all fields
 
24
    all objects
 
25
    inheritancies
 
26
 
 
27
.. i18n: All the ERP's pieces of data are accessible through "objects". As an example, there is a res.partner object to access the data concerning the partners, an account.invoice object for the data concerning the invoices, etc...
 
28
..
 
29
 
 
30
All the ERP's pieces of data are accessible through "objects". As an example, there is a res.partner object to access the data concerning the partners, an account.invoice object for the data concerning the invoices, etc...
 
31
 
 
32
.. i18n: Please note that there is an object for every type of resource, and not an
 
33
.. i18n: object per resource. We have thus a res.partner object to manage all the
 
34
.. i18n: partners and not a *res.partner* object per partner. If we talk in "object
 
35
.. i18n: oriented" terms, we could also say that there is an object per level.
 
36
..
 
37
 
 
38
Please note that there is an object for every type of resource, and not an
 
39
object per resource. We have thus a res.partner object to manage all the
 
40
partners and not a *res.partner* object per partner. If we talk in "object
 
41
oriented" terms, we could also say that there is an object per level.
 
42
 
 
43
.. i18n: The direct consequences is that all the methods of objects have a common parameter: the "ids" parameter. This specifies on which resources (for example, on which partner) the method must be applied. Precisely, this parameter contains a list of resource ids on which the method must be applied.
 
44
..
 
45
 
 
46
The direct consequences is that all the methods of objects have a common parameter: the "ids" parameter. This specifies on which resources (for example, on which partner) the method must be applied. Precisely, this parameter contains a list of resource ids on which the method must be applied.
 
47
 
 
48
.. i18n: For example, if we have two partners with the identifiers 1 and 5, and we want to call the res_partner method "send_email", we will write something like::
 
49
.. i18n: 
 
50
.. i18n:         res_partner.send_email(... , [1, 5], ...)
 
51
..
 
52
 
 
53
For example, if we have two partners with the identifiers 1 and 5, and we want to call the res_partner method "send_email", we will write something like::
 
54
 
 
55
        res_partner.send_email(... , [1, 5], ...)
 
56
 
 
57
.. i18n: We will see the exact syntax of object method calls further in this document.
 
58
..
 
59
 
 
60
We will see the exact syntax of object method calls further in this document.
 
61
 
 
62
.. i18n: In the following section, we will see how to define a new object. Then, we will check out the different methods of doing this.
 
63
..
 
64
 
 
65
In the following section, we will see how to define a new object. Then, we will check out the different methods of doing this.
 
66
 
 
67
.. i18n: For developers:
 
68
..
 
69
 
 
70
For developers:
 
71
 
 
72
.. i18n: * OpenERP "objects" are usually called classes in object oriented programming.
 
73
.. i18n: * A OpenERP "resource" is usually called an object in OO programming, instance of a class. 
 
74
..
 
75
 
 
76
* OpenERP "objects" are usually called classes in object oriented programming.
 
77
* A OpenERP "resource" is usually called an object in OO programming, instance of a class. 
 
78
 
 
79
.. i18n: It's a bit confusing when you try to program inside OpenERP, because the language used is Python, and Python is a fully object oriented language, and has objects and instances ...
 
80
..
 
81
 
 
82
It's a bit confusing when you try to program inside OpenERP, because the language used is Python, and Python is a fully object oriented language, and has objects and instances ...
 
83
 
 
84
.. i18n: Luckily, an OpenERP "resource" can be converted magically into a nice Python object using the "browse" class method (OpenERP object method).
 
85
..
 
86
 
 
87
Luckily, an OpenERP "resource" can be converted magically into a nice Python object using the "browse" class method (OpenERP object method).
 
88
 
 
89
.. i18n: The ORM - Object-relational mapping - Models
 
90
.. i18n: --------------------------------------------
 
91
..
 
92
 
 
93
The ORM - Object-relational mapping - Models
 
94
--------------------------------------------
 
95
 
 
96
.. i18n: The ORM, short for Object-Relational Mapping, is a central part of OpenERP.
 
97
..
 
98
 
 
99
The ORM, short for Object-Relational Mapping, is a central part of OpenERP.
 
100
 
 
101
.. i18n: In OpenERP, the data model is described and manipulated through Python classes
 
102
.. i18n: and objects. It is the ORM job to bridge the gap -- as transparently as
 
103
.. i18n: possible for the developer -- between Python and the underlying relational
 
104
.. i18n: database (PostgreSQL), which will provide the persistence we need for our
 
105
.. i18n: objects.
 
106
..
 
107
 
 
108
In OpenERP, the data model is described and manipulated through Python classes
 
109
and objects. It is the ORM job to bridge the gap -- as transparently as
 
110
possible for the developer -- between Python and the underlying relational
 
111
database (PostgreSQL), which will provide the persistence we need for our
 
112
objects.
 
113
 
 
114
.. i18n: OpenERP Object Attributes
 
115
.. i18n: -------------------------
 
116
..
 
117
 
 
118
OpenERP Object Attributes
 
119
-------------------------
 
120
 
 
121
.. i18n: Objects Introduction
 
122
.. i18n: ++++++++++++++++++++
 
123
..
 
124
 
 
125
Objects Introduction
 
126
++++++++++++++++++++
 
127
 
 
128
.. i18n: To define a new object, you must define a new Python class then instantiate it. This class must inherit from the osv class in the osv module.
 
129
..
 
130
 
 
131
To define a new object, you must define a new Python class then instantiate it. This class must inherit from the osv class in the osv module.
 
132
 
 
133
.. i18n: Object definition
 
134
.. i18n: +++++++++++++++++
 
135
..
 
136
 
 
137
Object definition
 
138
+++++++++++++++++
 
139
 
 
140
.. i18n: The first line of the object definition will always be of the form::
 
141
.. i18n: 
 
142
.. i18n:         class name_of_the_object(osv.osv):
 
143
.. i18n:                 _name = 'name.of.the.object'
 
144
.. i18n:                 _columns = { ... }
 
145
.. i18n:                 ...
 
146
.. i18n:         name_of_the_object()
 
147
..
 
148
 
 
149
The first line of the object definition will always be of the form::
 
150
 
 
151
        class name_of_the_object(osv.osv):
 
152
                _name = 'name.of.the.object'
 
153
                _columns = { ... }
 
154
                ...
 
155
        name_of_the_object()
 
156
 
 
157
.. i18n: An object is defined by declaring some fields with predefined names in the
 
158
.. i18n: class. Two of them are required (_name and _columns), the rest are optional.
 
159
.. i18n: The predefined fields are:
 
160
..
 
161
 
 
162
An object is defined by declaring some fields with predefined names in the
 
163
class. Two of them are required (_name and _columns), the rest are optional.
 
164
The predefined fields are:
 
165
 
 
166
.. i18n: Predefined fields
 
167
.. i18n: +++++++++++++++++
 
168
..
 
169
 
 
170
Predefined fields
 
171
+++++++++++++++++
 
172
 
 
173
.. i18n: `_auto`
 
174
.. i18n:   Determines whether a corresponding PostgreSQL table must be generated
 
175
.. i18n:   automatically from the object. Setting _auto to False can be useful in case
 
176
.. i18n:   of OpenERP objects generated from PostgreSQL views. See the "Reporting From
 
177
.. i18n:   PostgreSQL Views" section for more details.
 
178
..
 
179
 
 
180
`_auto`
 
181
  Determines whether a corresponding PostgreSQL table must be generated
 
182
  automatically from the object. Setting _auto to False can be useful in case
 
183
  of OpenERP objects generated from PostgreSQL views. See the "Reporting From
 
184
  PostgreSQL Views" section for more details.
 
185
 
 
186
.. i18n: `_columns (required)`
 
187
.. i18n:   The object fields. See the :ref:`fields <fields-link>` section for further details.
 
188
..
 
189
 
 
190
`_columns (required)`
 
191
  The object fields. See the :ref:`fields <fields-link>` section for further details.
 
192
 
 
193
.. i18n: `_constraints`
 
194
.. i18n:   The constraints on the object. See the constraints section for details.
 
195
..
 
196
 
 
197
`_constraints`
 
198
  The constraints on the object. See the constraints section for details.
 
199
 
 
200
.. i18n: `_sql_constraints`
 
201
.. i18n:   The SQL Constraint on the object. See the SQL constraints section for further details.
 
202
..
 
203
 
 
204
`_sql_constraints`
 
205
  The SQL Constraint on the object. See the SQL constraints section for further details.
 
206
 
 
207
.. i18n: `_defaults`
 
208
.. i18n:   The default values for some of the object's fields. See the default value section for details.
 
209
..
 
210
 
 
211
`_defaults`
 
212
  The default values for some of the object's fields. See the default value section for details.
 
213
 
 
214
.. i18n: `_inherit`
 
215
.. i18n:   The name of the osv object which the current object inherits from. See the :ref:`object inheritance section<inherit-link>`
 
216
.. i18n:   (first form) for further details.
 
217
..
 
218
 
 
219
`_inherit`
 
220
  The name of the osv object which the current object inherits from. See the :ref:`object inheritance section<inherit-link>`
 
221
  (first form) for further details.
 
222
 
 
223
.. i18n: `_inherits`
 
224
.. i18n:   The list of osv objects the object inherits from. This list must be given in
 
225
.. i18n:   a python dictionary of the form: {'name_of_the_parent_object':
 
226
.. i18n:   'name_of_the_field', ...}. See the :ref:`object inheritance section<inherits-link>` 
 
227
.. i18n:   (second form) for further details. Default value: {}.
 
228
..
 
229
 
 
230
`_inherits`
 
231
  The list of osv objects the object inherits from. This list must be given in
 
232
  a python dictionary of the form: {'name_of_the_parent_object':
 
233
  'name_of_the_field', ...}. See the :ref:`object inheritance section<inherits-link>` 
 
234
  (second form) for further details. Default value: {}.
 
235
 
 
236
.. i18n: `_log_access`
 
237
.. i18n:   Determines whether or not the write access to the resource must be logged.
 
238
.. i18n:   If true, four fields will be created in the SQL table: create_uid,
 
239
.. i18n:   create_date, write_uid, write_date. Those fields represent respectively the
 
240
.. i18n:   id of the user who created the record, the creation date of record, the id
 
241
.. i18n:   of the user who last modified the record, and the date of that last
 
242
.. i18n:   modification. This data may be obtained by using the perm_read method.
 
243
..
 
244
 
 
245
`_log_access`
 
246
  Determines whether or not the write access to the resource must be logged.
 
247
  If true, four fields will be created in the SQL table: create_uid,
 
248
  create_date, write_uid, write_date. Those fields represent respectively the
 
249
  id of the user who created the record, the creation date of record, the id
 
250
  of the user who last modified the record, and the date of that last
 
251
  modification. This data may be obtained by using the perm_read method.
 
252
 
 
253
.. i18n: `_name (required)`
 
254
.. i18n:   Name of the object. Default value: None.
 
255
..
 
256
 
 
257
`_name (required)`
 
258
  Name of the object. Default value: None.
 
259
 
 
260
.. i18n: `_order`
 
261
.. i18n:   Name of the fields used to sort the results of the search and read methods.
 
262
..
 
263
 
 
264
`_order`
 
265
  Name of the fields used to sort the results of the search and read methods.
 
266
 
 
267
.. i18n:   Default value: 'id'.
 
268
..
 
269
 
 
270
  Default value: 'id'.
 
271
 
 
272
.. i18n:   Examples::
 
273
.. i18n: 
 
274
.. i18n:     _order = "name"  
 
275
.. i18n:     _order = "date_order desc"
 
276
..
 
277
 
 
278
  Examples::
 
279
 
 
280
    _order = "name"  
 
281
    _order = "date_order desc"
 
282
 
 
283
.. i18n: `_rec_name`
 
284
.. i18n:   Name of the field in which the name of every resource is stored. Default
 
285
.. i18n:   value: 'name'. Note: by default, the name_get method simply returns the
 
286
.. i18n:   content of this field.
 
287
..
 
288
 
 
289
`_rec_name`
 
290
  Name of the field in which the name of every resource is stored. Default
 
291
  value: 'name'. Note: by default, the name_get method simply returns the
 
292
  content of this field.
 
293
 
 
294
.. i18n: `_sequence`
 
295
.. i18n:   Name of the SQL sequence that manages the ids for this object. Default value: None.
 
296
..
 
297
 
 
298
`_sequence`
 
299
  Name of the SQL sequence that manages the ids for this object. Default value: None.
 
300
 
 
301
.. i18n: `_sql`
 
302
.. i18n:  SQL code executed upon creation of the object (only if _auto is True). It means this code gets executed after the table is created.
 
303
..
 
304
 
 
305
`_sql`
 
306
 SQL code executed upon creation of the object (only if _auto is True). It means this code gets executed after the table is created.
 
307
 
 
308
.. i18n: `_table`
 
309
.. i18n:   Name of the SQL table. Default value: the value of the _name field above
 
310
.. i18n:   with the dots ( . ) replaced by underscores ( _ ). 
 
311
..
 
312
 
 
313
`_table`
 
314
  Name of the SQL table. Default value: the value of the _name field above
 
315
  with the dots ( . ) replaced by underscores ( _ ). 
 
316
 
 
317
.. i18n: .. _inherit-link:
 
318
.. i18n: 
 
319
.. i18n: Object Inheritance - _inherit
 
320
.. i18n: -----------------------------
 
321
..
 
322
 
 
323
.. _inherit-link:
 
324
 
 
325
Object Inheritance - _inherit
 
326
-----------------------------
 
327
 
 
328
.. i18n: Introduction
 
329
.. i18n: ++++++++++++
 
330
..
 
331
 
 
332
Introduction
 
333
++++++++++++
 
334
 
 
335
.. i18n: Objects may be inherited in some custom or specific modules. It is better to
 
336
.. i18n: inherit an object to add/modify some fields.
 
337
..
 
338
 
 
339
Objects may be inherited in some custom or specific modules. It is better to
 
340
inherit an object to add/modify some fields.
 
341
 
 
342
.. i18n: It is done with::
 
343
.. i18n: 
 
344
.. i18n:     _inherit='object.name'
 
345
..
 
346
 
 
347
It is done with::
 
348
 
 
349
    _inherit='object.name'
 
350
 
 
351
.. i18n: Extension of an object
 
352
.. i18n: ++++++++++++++++++++++
 
353
..
 
354
 
 
355
Extension of an object
 
356
++++++++++++++++++++++
 
357
 
 
358
.. i18n: There are two possible ways to do this kind of inheritance. Both ways result in
 
359
.. i18n: a new class of data, which holds parent fields and behaviour as well as
 
360
.. i18n: additional fields and behaviour, but they differ in heavy programatical
 
361
.. i18n: consequences.
 
362
..
 
363
 
 
364
There are two possible ways to do this kind of inheritance. Both ways result in
 
365
a new class of data, which holds parent fields and behaviour as well as
 
366
additional fields and behaviour, but they differ in heavy programatical
 
367
consequences.
 
368
 
 
369
.. i18n: While Example 1 creates a new subclass "custom_material" that may be "seen" or
 
370
.. i18n: "used" by any view or tree which handles "network.material", this will not be
 
371
.. i18n: the case for Example 2.
 
372
..
 
373
 
 
374
While Example 1 creates a new subclass "custom_material" that may be "seen" or
 
375
"used" by any view or tree which handles "network.material", this will not be
 
376
the case for Example 2.
 
377
 
 
378
.. i18n: This is due to the table (other.material) the new subclass is operating on,
 
379
.. i18n: which will never be recognized by previous "network.material" views or trees.
 
380
..
 
381
 
 
382
This is due to the table (other.material) the new subclass is operating on,
 
383
which will never be recognized by previous "network.material" views or trees.
 
384
 
 
385
.. i18n: Example 1::
 
386
.. i18n: 
 
387
.. i18n:     class custom_material(osv.osv):
 
388
.. i18n:         _name = 'network.material'
 
389
.. i18n:         _inherit = 'network.material'
 
390
.. i18n:         _columns = {
 
391
.. i18n:             'manuf_warranty': fields.boolean('Manufacturer warranty?'),
 
392
.. i18n:         }
 
393
.. i18n:         _defaults = {
 
394
.. i18n:             'manuf_warranty': lambda *a: False,
 
395
.. i18n:         }
 
396
.. i18n:         custom_material()
 
397
..
 
398
 
 
399
Example 1::
 
400
 
 
401
    class custom_material(osv.osv):
 
402
        _name = 'network.material'
 
403
        _inherit = 'network.material'
 
404
        _columns = {
 
405
            'manuf_warranty': fields.boolean('Manufacturer warranty?'),
 
406
        }
 
407
        _defaults = {
 
408
            'manuf_warranty': lambda *a: False,
 
409
        }
 
410
        custom_material()
 
411
 
 
412
.. i18n: .. tip:: Notice
 
413
.. i18n: 
 
414
.. i18n:     _name == _inherit
 
415
..
 
416
 
 
417
.. tip:: Notice
 
418
 
 
419
    _name == _inherit
 
420
 
 
421
.. i18n: In this example, the 'custom_material' will add a new field 'manuf_warranty' to
 
422
.. i18n: the object 'network.material'. New instances of this class will be visible by
 
423
.. i18n: views or trees operating on the superclasses table 'network.material'.
 
424
..
 
425
 
 
426
In this example, the 'custom_material' will add a new field 'manuf_warranty' to
 
427
the object 'network.material'. New instances of this class will be visible by
 
428
views or trees operating on the superclasses table 'network.material'.
 
429
 
 
430
.. i18n: This inheritancy is usually called "class inheritance" in Object oriented
 
431
.. i18n: design. The child inherits data (fields) and behavior (functions) of his
 
432
.. i18n: parent.
 
433
..
 
434
 
 
435
This inheritancy is usually called "class inheritance" in Object oriented
 
436
design. The child inherits data (fields) and behavior (functions) of his
 
437
parent.
 
438
 
 
439
.. i18n: Example 2::
 
440
.. i18n: 
 
441
.. i18n:     class other_material(osv.osv):
 
442
.. i18n:         _name = 'other.material'
 
443
.. i18n:         _inherit = 'network.material'
 
444
.. i18n:         _columns = {
 
445
.. i18n:             'manuf_warranty': fields.boolean('Manufacturer warranty?'),
 
446
.. i18n:         }
 
447
.. i18n:         _defaults = {
 
448
.. i18n:             'manuf_warranty': lambda *a: False,
 
449
.. i18n:         }
 
450
.. i18n:         other_material()
 
451
..
 
452
 
 
453
Example 2::
 
454
 
 
455
    class other_material(osv.osv):
 
456
        _name = 'other.material'
 
457
        _inherit = 'network.material'
 
458
        _columns = {
 
459
            'manuf_warranty': fields.boolean('Manufacturer warranty?'),
 
460
        }
 
461
        _defaults = {
 
462
            'manuf_warranty': lambda *a: False,
 
463
        }
 
464
        other_material()
 
465
 
 
466
.. i18n: .. tip:: Notice
 
467
.. i18n: 
 
468
.. i18n:     _name != _inherit
 
469
..
 
470
 
 
471
.. tip:: Notice
 
472
 
 
473
    _name != _inherit
 
474
 
 
475
.. i18n: In this example, the 'other_material' will hold all fields specified by
 
476
.. i18n: 'network.material' and it will additionally hold a new field 'manuf_warranty'.
 
477
.. i18n: All those fields will be part of the table 'other.material'. New instances of
 
478
.. i18n: this class will therefore never been seen by views or trees operating on the
 
479
.. i18n: superclasses table 'network.material'.
 
480
..
 
481
 
 
482
In this example, the 'other_material' will hold all fields specified by
 
483
'network.material' and it will additionally hold a new field 'manuf_warranty'.
 
484
All those fields will be part of the table 'other.material'. New instances of
 
485
this class will therefore never been seen by views or trees operating on the
 
486
superclasses table 'network.material'.
 
487
 
 
488
.. i18n: This type of inheritancy is known as "inheritance by prototyping" (e.g.
 
489
.. i18n: Javascript), because the newly created subclass "copies" all fields from the
 
490
.. i18n: specified superclass (prototype). The child inherits data (fields) and behavior
 
491
.. i18n: (functions) of his parent.
 
492
..
 
493
 
 
494
This type of inheritancy is known as "inheritance by prototyping" (e.g.
 
495
Javascript), because the newly created subclass "copies" all fields from the
 
496
specified superclass (prototype). The child inherits data (fields) and behavior
 
497
(functions) of his parent.
 
498
 
 
499
.. i18n: .. _inherits-link:
 
500
.. i18n: 
 
501
.. i18n: Inheritance by Delegation - _inherits
 
502
.. i18n: -------------------------------------
 
503
..
 
504
 
 
505
.. _inherits-link:
 
506
 
 
507
Inheritance by Delegation - _inherits
 
508
-------------------------------------
 
509
 
 
510
.. i18n:  **Syntax :**::
 
511
.. i18n: 
 
512
.. i18n:     class tiny_object(osv.osv)
 
513
.. i18n:         _name = 'tiny.object'
 
514
.. i18n:         _table = 'tiny_object'
 
515
.. i18n:         _inherits = {
 
516
.. i18n:             'tiny.object_a': 'object_a_id',
 
517
.. i18n:             'tiny.object_b': 'object_b_id',
 
518
.. i18n:             ... ,
 
519
.. i18n:             'tiny.object_n': 'object_n_id'
 
520
.. i18n:         }
 
521
.. i18n:         (...)
 
522
..
 
523
 
 
524
 **Syntax :**::
 
525
 
 
526
    class tiny_object(osv.osv)
 
527
        _name = 'tiny.object'
 
528
        _table = 'tiny_object'
 
529
        _inherits = {
 
530
            'tiny.object_a': 'object_a_id',
 
531
            'tiny.object_b': 'object_b_id',
 
532
            ... ,
 
533
            'tiny.object_n': 'object_n_id'
 
534
        }
 
535
        (...)
 
536
 
 
537
.. i18n: The object 'tiny.object' inherits from all the columns and all the methods from
 
538
.. i18n: the n objects 'tiny.object_a', ..., 'tiny.object_n'.
 
539
..
 
540
 
 
541
The object 'tiny.object' inherits from all the columns and all the methods from
 
542
the n objects 'tiny.object_a', ..., 'tiny.object_n'.
 
543
 
 
544
.. i18n: To inherit from multiple tables, the technique consists in adding one column to
 
545
.. i18n: the table tiny_object per inherited object. This column will store a foreign
 
546
.. i18n: key (an id from another table). The values *'object_a_id' 'object_b_id' ...
 
547
.. i18n: 'object_n_id'* are of type string and determine the title of the columns in
 
548
.. i18n: which the foreign keys from 'tiny.object_a', ..., 'tiny.object_n' are stored.
 
549
..
 
550
 
 
551
To inherit from multiple tables, the technique consists in adding one column to
 
552
the table tiny_object per inherited object. This column will store a foreign
 
553
key (an id from another table). The values *'object_a_id' 'object_b_id' ...
 
554
'object_n_id'* are of type string and determine the title of the columns in
 
555
which the foreign keys from 'tiny.object_a', ..., 'tiny.object_n' are stored.
 
556
 
 
557
.. i18n: This inheritance mechanism is usually called " *instance inheritance* "  or  "
 
558
.. i18n: *value inheritance* ". A resource (instance) has the VALUES of its parents.
 
559
..
 
560
 
 
561
This inheritance mechanism is usually called " *instance inheritance* "  or  "
 
562
*value inheritance* ". A resource (instance) has the VALUES of its parents.
 
563
 
 
564
.. i18n: .. _fields-link:
 
565
.. i18n: 
 
566
.. i18n: Fields Introduction
 
567
.. i18n: -------------------
 
568
..
 
569
 
 
570
.. _fields-link:
 
571
 
 
572
Fields Introduction
 
573
-------------------
 
574
 
 
575
.. i18n: Objects may contain different types of fields. Those types can be divided into
 
576
.. i18n: three categories: simple types, relation types and functional fields. The
 
577
.. i18n: simple types are integers, floats, booleans, strings, etc ... ; the relation
 
578
.. i18n: types are used to represent relations between objects (one2one, one2many,
 
579
.. i18n: many2one). Functional fields are special fields because they are not stored in
 
580
.. i18n: the database but calculated in real time given other fields of the view.
 
581
..
 
582
 
 
583
Objects may contain different types of fields. Those types can be divided into
 
584
three categories: simple types, relation types and functional fields. The
 
585
simple types are integers, floats, booleans, strings, etc ... ; the relation
 
586
types are used to represent relations between objects (one2one, one2many,
 
587
many2one). Functional fields are special fields because they are not stored in
 
588
the database but calculated in real time given other fields of the view.
 
589
 
 
590
.. i18n: Here's the header of the initialization method of the class any field defined
 
591
.. i18n: in OpenERP inherits (as you can see in server/bin/osv/fields.py)::
 
592
.. i18n: 
 
593
.. i18n:     def __init__(self, string='unknown', required=False, readonly=False,
 
594
.. i18n:                  domain=None, context="", states=None, priority=0, change_default=False, size=None,
 
595
.. i18n:                  ondelete="set null", translate=False, select=False, **args) :
 
596
..
 
597
 
 
598
Here's the header of the initialization method of the class any field defined
 
599
in OpenERP inherits (as you can see in server/bin/osv/fields.py)::
 
600
 
 
601
    def __init__(self, string='unknown', required=False, readonly=False,
 
602
                 domain=None, context="", states=None, priority=0, change_default=False, size=None,
 
603
                 ondelete="set null", translate=False, select=False, **args) :
 
604
 
 
605
.. i18n: There are a common set of optional parameters that are available to most field
 
606
.. i18n: types:
 
607
..
 
608
 
 
609
There are a common set of optional parameters that are available to most field
 
610
types:
 
611
 
 
612
.. i18n: :change_default: 
 
613
.. i18n:        Whether or not the user can define default values on other fields depending 
 
614
.. i18n:        on the value of this field. Those default values need to be defined in
 
615
.. i18n:        the ir.values table.
 
616
.. i18n: :help: 
 
617
.. i18n:        A description of how the field should be used: longer and more descriptive
 
618
.. i18n:        than `string`. It will appear in a tooltip when the mouse hovers over the 
 
619
.. i18n:        field.
 
620
.. i18n: :ondelete: 
 
621
.. i18n:        How to handle deletions in a related record. Allowable values are: 
 
622
.. i18n:        'restrict', 'no action', 'cascade', 'set null', and 'set default'.
 
623
.. i18n: :priority: Not used?
 
624
.. i18n: :readonly: `True` if the user cannot edit this field, otherwise `False`.
 
625
.. i18n: :required:
 
626
.. i18n:        `True` if this field must have a value before the object can be saved, 
 
627
.. i18n:        otherwise `False`.
 
628
.. i18n: :size: The size of the field in the database: number characters or digits.
 
629
.. i18n: :states:
 
630
.. i18n:        Lets you override other parameters for specific states of this object. 
 
631
.. i18n:        Accepts a dictionary with the state names as keys and a list of name/value 
 
632
.. i18n:        tuples as the values. For example: `states={'posted':[('readonly',True)]}`
 
633
.. i18n: :string: 
 
634
.. i18n:        The field name as it should appear in a label or column header. Strings
 
635
.. i18n:        containing non-ASCII characters must use python unicode objects. 
 
636
.. i18n:        For example: `'tested': fields.boolean(u'Testé')` 
 
637
.. i18n: :translate:
 
638
.. i18n:        `True` if the *content* of this field should be translated, otherwise 
 
639
.. i18n:        `False`.
 
640
..
 
641
 
 
642
:change_default: 
 
643
        Whether or not the user can define default values on other fields depending 
 
644
        on the value of this field. Those default values need to be defined in
 
645
        the ir.values table.
 
646
:help: 
 
647
        A description of how the field should be used: longer and more descriptive
 
648
        than `string`. It will appear in a tooltip when the mouse hovers over the 
 
649
        field.
 
650
:ondelete: 
 
651
        How to handle deletions in a related record. Allowable values are: 
 
652
        'restrict', 'no action', 'cascade', 'set null', and 'set default'.
 
653
:priority: Not used?
 
654
:readonly: `True` if the user cannot edit this field, otherwise `False`.
 
655
:required:
 
656
        `True` if this field must have a value before the object can be saved, 
 
657
        otherwise `False`.
 
658
:size: The size of the field in the database: number characters or digits.
 
659
:states:
 
660
        Lets you override other parameters for specific states of this object. 
 
661
        Accepts a dictionary with the state names as keys and a list of name/value 
 
662
        tuples as the values. For example: `states={'posted':[('readonly',True)]}`
 
663
:string: 
 
664
        The field name as it should appear in a label or column header. Strings
 
665
        containing non-ASCII characters must use python unicode objects. 
 
666
        For example: `'tested': fields.boolean(u'Testé')` 
 
667
:translate:
 
668
        `True` if the *content* of this field should be translated, otherwise 
 
669
        `False`.
 
670
 
 
671
.. i18n: There are also some optional parameters that are specific to some field types:
 
672
..
 
673
 
 
674
There are also some optional parameters that are specific to some field types:
 
675
 
 
676
.. i18n: :context: 
 
677
.. i18n:        Define a variable's value visible in the view's context or an on-change 
 
678
.. i18n:        function. Used when searching child table of `one2many` relationship?
 
679
.. i18n: :domain: 
 
680
.. i18n:     Domain restriction on a relational field.
 
681
..
 
682
 
 
683
:context: 
 
684
        Define a variable's value visible in the view's context or an on-change 
 
685
        function. Used when searching child table of `one2many` relationship?
 
686
:domain: 
 
687
    Domain restriction on a relational field.
 
688
 
 
689
.. i18n:     Default value: []. 
 
690
..
 
691
 
 
692
    Default value: []. 
 
693
 
 
694
.. i18n:     Example: domain=[('field','=',value)])
 
695
.. i18n: :invisible: Hide the field's value in forms. For example, a password.
 
696
.. i18n: :on_change:
 
697
.. i18n:        Default value for the `on_change` attribute in the view. This will launch
 
698
.. i18n:        a function on the server when the field changes in the client. For example,
 
699
.. i18n:        `on_change="onchange_shop_id(shop_id)"`. 
 
700
.. i18n: :relation:
 
701
.. i18n:        Used when a field is an id reference to another table. This is the name of
 
702
.. i18n:        the table to look in. Most commonly used with related and function field
 
703
.. i18n:        types.
 
704
.. i18n: :select: 
 
705
.. i18n:        Default value for the `select` attribute in the view. 1 means basic search,
 
706
.. i18n:        and 2 means advanced search.
 
707
..
 
708
 
 
709
    Example: domain=[('field','=',value)])
 
710
:invisible: Hide the field's value in forms. For example, a password.
 
711
:on_change:
 
712
        Default value for the `on_change` attribute in the view. This will launch
 
713
        a function on the server when the field changes in the client. For example,
 
714
        `on_change="onchange_shop_id(shop_id)"`. 
 
715
:relation:
 
716
        Used when a field is an id reference to another table. This is the name of
 
717
        the table to look in. Most commonly used with related and function field
 
718
        types.
 
719
:select: 
 
720
        Default value for the `select` attribute in the view. 1 means basic search,
 
721
        and 2 means advanced search.
 
722
 
 
723
.. i18n: Type of Fields
 
724
.. i18n: --------------
 
725
..
 
726
 
 
727
Type of Fields
 
728
--------------
 
729
 
 
730
.. i18n: Basic Types
 
731
.. i18n: +++++++++++
 
732
..
 
733
 
 
734
Basic Types
 
735
+++++++++++
 
736
 
 
737
.. i18n: :boolean:
 
738
..
 
739
 
 
740
:boolean:
 
741
 
 
742
.. i18n:        A boolean (true, false).
 
743
..
 
744
 
 
745
        A boolean (true, false).
 
746
 
 
747
.. i18n:        Syntax::
 
748
.. i18n: 
 
749
.. i18n:                 fields.boolean('Field Name' [, Optional Parameters]),
 
750
..
 
751
 
 
752
        Syntax::
 
753
 
 
754
                fields.boolean('Field Name' [, Optional Parameters]),
 
755
 
 
756
.. i18n: :integer:
 
757
..
 
758
 
 
759
:integer:
 
760
 
 
761
.. i18n:        An integer.
 
762
..
 
763
 
 
764
        An integer.
 
765
 
 
766
.. i18n:        Syntax::
 
767
.. i18n: 
 
768
.. i18n:                 fields.integer('Field Name' [, Optional Parameters]),
 
769
..
 
770
 
 
771
        Syntax::
 
772
 
 
773
                fields.integer('Field Name' [, Optional Parameters]),
 
774
 
 
775
.. i18n: :float:
 
776
..
 
777
 
 
778
:float:
 
779
 
 
780
.. i18n:     A floating point number.
 
781
..
 
782
 
 
783
    A floating point number.
 
784
 
 
785
.. i18n:     Syntax::
 
786
.. i18n: 
 
787
.. i18n:                 fields.float('Field Name' [, Optional Parameters]),
 
788
.. i18n: 
 
789
.. i18n:     .. note::
 
790
.. i18n: 
 
791
.. i18n:             The optional parameter digits defines the precision and scale of the
 
792
.. i18n:             number. The scale being the number of digits after the decimal point
 
793
.. i18n:             whereas the precision is the total number of significant digits in the
 
794
.. i18n:             number (before and after the decimal point). If the parameter digits is
 
795
.. i18n:             not present, the number will be a double precision floating point number.
 
796
.. i18n:             Warning: these floating-point numbers are inexact (not any value can be
 
797
.. i18n:             converted to its binary representation) and this can lead to rounding
 
798
.. i18n:             errors. You should always use the digits parameter for monetary amounts.
 
799
.. i18n: 
 
800
.. i18n:     Example::
 
801
.. i18n: 
 
802
.. i18n:         'rate': fields.float(
 
803
.. i18n:             'Relative Change rate',
 
804
.. i18n:             digits=(12,6) [,
 
805
.. i18n:             Optional Parameters]),
 
806
..
 
807
 
 
808
    Syntax::
 
809
 
 
810
                fields.float('Field Name' [, Optional Parameters]),
 
811
 
 
812
    .. note::
 
813
 
 
814
            The optional parameter digits defines the precision and scale of the
 
815
            number. The scale being the number of digits after the decimal point
 
816
            whereas the precision is the total number of significant digits in the
 
817
            number (before and after the decimal point). If the parameter digits is
 
818
            not present, the number will be a double precision floating point number.
 
819
            Warning: these floating-point numbers are inexact (not any value can be
 
820
            converted to its binary representation) and this can lead to rounding
 
821
            errors. You should always use the digits parameter for monetary amounts.
 
822
 
 
823
    Example::
 
824
 
 
825
        'rate': fields.float(
 
826
            'Relative Change rate',
 
827
            digits=(12,6) [,
 
828
            Optional Parameters]),
 
829
 
 
830
.. i18n: :char:
 
831
..
 
832
 
 
833
:char:
 
834
 
 
835
.. i18n:   A string of limited length. The required size parameter determines its size.
 
836
..
 
837
 
 
838
  A string of limited length. The required size parameter determines its size.
 
839
 
 
840
.. i18n:   Syntax::
 
841
.. i18n: 
 
842
.. i18n:        fields.char(
 
843
.. i18n:                'Field Name', 
 
844
.. i18n:                size=n [, 
 
845
.. i18n:                Optional Parameters]), # where ''n'' is an integer.
 
846
.. i18n: 
 
847
.. i18n:   Example::
 
848
.. i18n: 
 
849
.. i18n:         'city' : fields.char('City Name', size=30, required=True),
 
850
..
 
851
 
 
852
  Syntax::
 
853
 
 
854
        fields.char(
 
855
                'Field Name', 
 
856
                size=n [, 
 
857
                Optional Parameters]), # where ''n'' is an integer.
 
858
 
 
859
  Example::
 
860
 
 
861
        'city' : fields.char('City Name', size=30, required=True),
 
862
 
 
863
.. i18n: :text:
 
864
..
 
865
 
 
866
:text:
 
867
 
 
868
.. i18n:   A text field with no limit in length.
 
869
..
 
870
 
 
871
  A text field with no limit in length.
 
872
 
 
873
.. i18n:   Syntax::
 
874
.. i18n: 
 
875
.. i18n:                 fields.text('Field Name' [, Optional Parameters]),
 
876
..
 
877
 
 
878
  Syntax::
 
879
 
 
880
                fields.text('Field Name' [, Optional Parameters]),
 
881
 
 
882
.. i18n: :date:
 
883
..
 
884
 
 
885
:date:
 
886
 
 
887
.. i18n:   A date.
 
888
..
 
889
 
 
890
  A date.
 
891
 
 
892
.. i18n:   Syntax::
 
893
.. i18n: 
 
894
.. i18n:                 fields.date('Field Name' [, Optional Parameters]),
 
895
..
 
896
 
 
897
  Syntax::
 
898
 
 
899
                fields.date('Field Name' [, Optional Parameters]),
 
900
 
 
901
.. i18n: :datetime:
 
902
..
 
903
 
 
904
:datetime:
 
905
 
 
906
.. i18n:   Allows to store a date and the time of day in the same field.
 
907
..
 
908
 
 
909
  Allows to store a date and the time of day in the same field.
 
910
 
 
911
.. i18n:   Syntax::
 
912
.. i18n: 
 
913
.. i18n:                 fields.datetime('Field Name' [, Optional Parameters]),
 
914
..
 
915
 
 
916
  Syntax::
 
917
 
 
918
                fields.datetime('Field Name' [, Optional Parameters]),
 
919
 
 
920
.. i18n: :binary:
 
921
..
 
922
 
 
923
:binary:
 
924
 
 
925
.. i18n:   A binary chain
 
926
..
 
927
 
 
928
  A binary chain
 
929
 
 
930
.. i18n: :selection:
 
931
..
 
932
 
 
933
:selection:
 
934
 
 
935
.. i18n:   A field which allows the user to make a selection between various predefined values.
 
936
..
 
937
 
 
938
  A field which allows the user to make a selection between various predefined values.
 
939
 
 
940
.. i18n:   Syntax::
 
941
.. i18n: 
 
942
.. i18n:                 fields.selection((('n','Unconfirmed'), ('c','Confirmed')),
 
943
.. i18n:                                    'Field Name' [, Optional Parameters]),
 
944
.. i18n: 
 
945
.. i18n:   .. note::
 
946
.. i18n: 
 
947
.. i18n:              Format of the selection parameter: tuple of tuples of strings of the form::
 
948
.. i18n: 
 
949
.. i18n:                 (('key_or_value', 'string_to_display'), ... )
 
950
.. i18n:                 
 
951
.. i18n:   .. note::
 
952
.. i18n:              You can specify a function that will return the tuple. Example ::
 
953
.. i18n:              
 
954
.. i18n:                  def _get_selection(self, cursor, user_id, context=None):
 
955
.. i18n:                      return (
 
956
.. i18n:                        ('choice1', 'This is the choice 1'), 
 
957
.. i18n:                        ('choice2', 'This is the choice 2'))
 
958
.. i18n:                      
 
959
.. i18n:                  _columns = {
 
960
.. i18n:                     'sel' : fields.selection(
 
961
.. i18n:                        _get_selection, 
 
962
.. i18n:                        'What do you want ?')
 
963
.. i18n:                  }
 
964
.. i18n: 
 
965
.. i18n:   *Example*
 
966
.. i18n: 
 
967
.. i18n:   Using relation fields **many2one** with **selection**. In fields definitions add::
 
968
.. i18n: 
 
969
.. i18n:         ...,
 
970
.. i18n:         'my_field': fields.many2one(
 
971
.. i18n:                'mymodule.relation.model', 
 
972
.. i18n:                'Title', 
 
973
.. i18n:                selection=_sel_func),
 
974
.. i18n:         ...,
 
975
.. i18n: 
 
976
.. i18n:   And then define the _sel_func like this (but before the fields definitions)::
 
977
.. i18n: 
 
978
.. i18n:         def _sel_func(self, cr, uid, context=None):
 
979
.. i18n:             obj = self.pool.get('mymodule.relation.model')
 
980
.. i18n:             ids = obj.search(cr, uid, [])
 
981
.. i18n:             res = obj.read(cr, uid, ids, ['name', 'id'], context)
 
982
.. i18n:             res = [(r['id'], r['name']) for r in res]
 
983
.. i18n:             return res
 
984
..
 
985
 
 
986
  Syntax::
 
987
 
 
988
                fields.selection((('n','Unconfirmed'), ('c','Confirmed')),
 
989
                                   'Field Name' [, Optional Parameters]),
 
990
 
 
991
  .. note::
 
992
 
 
993
             Format of the selection parameter: tuple of tuples of strings of the form::
 
994
 
 
995
                (('key_or_value', 'string_to_display'), ... )
 
996
                
 
997
  .. note::
 
998
             You can specify a function that will return the tuple. Example ::
 
999
             
 
1000
                 def _get_selection(self, cursor, user_id, context=None):
 
1001
                     return (
 
1002
                        ('choice1', 'This is the choice 1'), 
 
1003
                        ('choice2', 'This is the choice 2'))
 
1004
                     
 
1005
                 _columns = {
 
1006
                    'sel' : fields.selection(
 
1007
                        _get_selection, 
 
1008
                        'What do you want ?')
 
1009
                 }
 
1010
 
 
1011
  *Example*
 
1012
 
 
1013
  Using relation fields **many2one** with **selection**. In fields definitions add::
 
1014
 
 
1015
        ...,
 
1016
        'my_field': fields.many2one(
 
1017
                'mymodule.relation.model', 
 
1018
                'Title', 
 
1019
                selection=_sel_func),
 
1020
        ...,
 
1021
 
 
1022
  And then define the _sel_func like this (but before the fields definitions)::
 
1023
 
 
1024
        def _sel_func(self, cr, uid, context=None):
 
1025
            obj = self.pool.get('mymodule.relation.model')
 
1026
            ids = obj.search(cr, uid, [])
 
1027
            res = obj.read(cr, uid, ids, ['name', 'id'], context)
 
1028
            res = [(r['id'], r['name']) for r in res]
 
1029
            return res
 
1030
 
 
1031
.. i18n: Relational Types
 
1032
.. i18n: ++++++++++++++++
 
1033
..
 
1034
 
 
1035
Relational Types
 
1036
++++++++++++++++
 
1037
 
 
1038
.. i18n: :one2one:
 
1039
..
 
1040
 
 
1041
:one2one:
 
1042
 
 
1043
.. i18n:   A one2one field expresses a one:to:one relation between two objects. It is
 
1044
.. i18n:   deprecated. Use many2one instead.
 
1045
..
 
1046
 
 
1047
  A one2one field expresses a one:to:one relation between two objects. It is
 
1048
  deprecated. Use many2one instead.
 
1049
 
 
1050
.. i18n:   Syntax::
 
1051
.. i18n: 
 
1052
.. i18n:                 fields.one2one('other.object.name', 'Field Name')
 
1053
..
 
1054
 
 
1055
  Syntax::
 
1056
 
 
1057
                fields.one2one('other.object.name', 'Field Name')
 
1058
 
 
1059
.. i18n: :many2one:
 
1060
..
 
1061
 
 
1062
:many2one:
 
1063
 
 
1064
.. i18n:   Associates this object to a parent object via this Field. For example
 
1065
.. i18n:   Department an Employee belongs to would Many to one. i.e Many employees will
 
1066
.. i18n:   belong to a Department
 
1067
..
 
1068
 
 
1069
  Associates this object to a parent object via this Field. For example
 
1070
  Department an Employee belongs to would Many to one. i.e Many employees will
 
1071
  belong to a Department
 
1072
 
 
1073
.. i18n:   Syntax::
 
1074
.. i18n: 
 
1075
.. i18n:                fields.many2one(
 
1076
.. i18n:                        'other.object.name', 
 
1077
.. i18n:                        'Field Name', 
 
1078
.. i18n:                        optional parameters)
 
1079
.. i18n: 
 
1080
.. i18n:   Optional parameters:
 
1081
.. i18n:   
 
1082
.. i18n:     - ondelete: What should happen when the resource this field points to is deleted.
 
1083
.. i18n:             + Predefined value: "cascade", "set null", "restrict", "no action", "set default"
 
1084
.. i18n:             + Default value: "set null"
 
1085
.. i18n:     - required: True
 
1086
.. i18n:     - readonly: True
 
1087
.. i18n:     - select: True - (creates an index on the Foreign Key field)
 
1088
.. i18n: 
 
1089
.. i18n:   *Example* ::
 
1090
.. i18n: 
 
1091
.. i18n:                 'commercial': fields.many2one(
 
1092
.. i18n:                        'res.users', 
 
1093
.. i18n:                        'Commercial', 
 
1094
.. i18n:                        ondelete='cascade'),
 
1095
..
 
1096
 
 
1097
  Syntax::
 
1098
 
 
1099
                fields.many2one(
 
1100
                        'other.object.name', 
 
1101
                        'Field Name', 
 
1102
                        optional parameters)
 
1103
 
 
1104
  Optional parameters:
 
1105
  
 
1106
    - ondelete: What should happen when the resource this field points to is deleted.
 
1107
            + Predefined value: "cascade", "set null", "restrict", "no action", "set default"
 
1108
            + Default value: "set null"
 
1109
    - required: True
 
1110
    - readonly: True
 
1111
    - select: True - (creates an index on the Foreign Key field)
 
1112
 
 
1113
  *Example* ::
 
1114
 
 
1115
                'commercial': fields.many2one(
 
1116
                        'res.users', 
 
1117
                        'Commercial', 
 
1118
                        ondelete='cascade'),
 
1119
 
 
1120
.. i18n: :one2many:
 
1121
..
 
1122
 
 
1123
:one2many:
 
1124
 
 
1125
.. i18n:   TODO
 
1126
..
 
1127
 
 
1128
  TODO
 
1129
 
 
1130
.. i18n:   Syntax::
 
1131
.. i18n: 
 
1132
.. i18n:                 fields.one2many(
 
1133
.. i18n:                        'other.object.name', 
 
1134
.. i18n:                        'Field relation id', 
 
1135
.. i18n:                        'Fieldname', 
 
1136
.. i18n:                        optional parameter)
 
1137
.. i18n: 
 
1138
.. i18n:   Optional parameters:
 
1139
.. i18n:                 - invisible: True/False
 
1140
.. i18n:                 - states: ?
 
1141
.. i18n:                 - readonly: True/False
 
1142
.. i18n: 
 
1143
.. i18n:   *Example* ::
 
1144
.. i18n: 
 
1145
.. i18n:                 'address': fields.one2many(
 
1146
.. i18n:                        'res.partner.address', 
 
1147
.. i18n:                        'partner_id', 
 
1148
.. i18n:                        'Contacts'),
 
1149
..
 
1150
 
 
1151
  Syntax::
 
1152
 
 
1153
                fields.one2many(
 
1154
                        'other.object.name', 
 
1155
                        'Field relation id', 
 
1156
                        'Fieldname', 
 
1157
                        optional parameter)
 
1158
 
 
1159
  Optional parameters:
 
1160
                - invisible: True/False
 
1161
                - states: ?
 
1162
                - readonly: True/False
 
1163
 
 
1164
  *Example* ::
 
1165
 
 
1166
                'address': fields.one2many(
 
1167
                        'res.partner.address', 
 
1168
                        'partner_id', 
 
1169
                        'Contacts'),
 
1170
 
 
1171
.. i18n: :many2many:
 
1172
..
 
1173
 
 
1174
:many2many:
 
1175
 
 
1176
.. i18n:         TODO
 
1177
..
 
1178
 
 
1179
        TODO
 
1180
 
 
1181
.. i18n:         Syntax::
 
1182
.. i18n: 
 
1183
.. i18n:                 fields.many2many('other.object.name',
 
1184
.. i18n:                                  'relation object',
 
1185
.. i18n:                                  'actual.object.id',
 
1186
.. i18n:                                  'other.object.id',                                 
 
1187
.. i18n:                                  'Field Name')
 
1188
.. i18n: 
 
1189
.. i18n:         Where:
 
1190
.. i18n:                 - other.object.name is the other object which belongs to the relation
 
1191
.. i18n:                 - relation object is the table that makes the link
 
1192
.. i18n:                 - actual.object.id and other.object.id are the fields' names used in the relation table
 
1193
.. i18n: 
 
1194
.. i18n:         Example::
 
1195
.. i18n: 
 
1196
.. i18n:                 'category_ids':
 
1197
.. i18n:                    fields.many2many(
 
1198
.. i18n:                     'res.partner.category',
 
1199
.. i18n:                     'res_partner_category_rel',
 
1200
.. i18n:                     'partner_id',
 
1201
.. i18n:                     'category_id',
 
1202
.. i18n:                     'Categories'),
 
1203
.. i18n: 
 
1204
.. i18n:         To make it bidirectional (= create a field in the other object)::
 
1205
.. i18n: 
 
1206
.. i18n:                 class other_object_name2(osv.osv):
 
1207
.. i18n:                     _inherit = 'other.object.name'
 
1208
.. i18n:                     _columns = {
 
1209
.. i18n:                         'other_fields': fields.many2many(
 
1210
.. i18n:                             'actual.object.name', 
 
1211
.. i18n:                             'relation object', 
 
1212
.. i18n:                             'actual.object.id', 
 
1213
.. i18n:                             'other.object.id', 
 
1214
.. i18n:                             'Other Field Name'),
 
1215
.. i18n:                     }
 
1216
.. i18n:                 other_object_name2()
 
1217
.. i18n: 
 
1218
.. i18n:         Example::
 
1219
.. i18n: 
 
1220
.. i18n:                 class res_partner_category2(osv.osv):
 
1221
.. i18n:                     _inherit = 'res.partner.category'
 
1222
.. i18n:                     _columns = {
 
1223
.. i18n:                         'partner_ids': fields.many2many(
 
1224
.. i18n:                             'res.partner', 
 
1225
.. i18n:                             'res_partner_category_rel', 
 
1226
.. i18n:                             'category_id', 
 
1227
.. i18n:                             'partner_id', 
 
1228
.. i18n:                             'Partners'),
 
1229
.. i18n:                     }
 
1230
.. i18n:                 res_partner_category2()
 
1231
..
 
1232
 
 
1233
        Syntax::
 
1234
 
 
1235
                fields.many2many('other.object.name',
 
1236
                                 'relation object',
 
1237
                                 'actual.object.id',
 
1238
                                 'other.object.id',                                 
 
1239
                                 'Field Name')
 
1240
 
 
1241
        Where:
 
1242
                - other.object.name is the other object which belongs to the relation
 
1243
                - relation object is the table that makes the link
 
1244
                - actual.object.id and other.object.id are the fields' names used in the relation table
 
1245
 
 
1246
        Example::
 
1247
 
 
1248
                'category_ids':
 
1249
                   fields.many2many(
 
1250
                    'res.partner.category',
 
1251
                    'res_partner_category_rel',
 
1252
                    'partner_id',
 
1253
                    'category_id',
 
1254
                    'Categories'),
 
1255
 
 
1256
        To make it bidirectional (= create a field in the other object)::
 
1257
 
 
1258
                class other_object_name2(osv.osv):
 
1259
                    _inherit = 'other.object.name'
 
1260
                    _columns = {
 
1261
                        'other_fields': fields.many2many(
 
1262
                            'actual.object.name', 
 
1263
                            'relation object', 
 
1264
                            'actual.object.id', 
 
1265
                            'other.object.id', 
 
1266
                            'Other Field Name'),
 
1267
                    }
 
1268
                other_object_name2()
 
1269
 
 
1270
        Example::
 
1271
 
 
1272
                class res_partner_category2(osv.osv):
 
1273
                    _inherit = 'res.partner.category'
 
1274
                    _columns = {
 
1275
                        'partner_ids': fields.many2many(
 
1276
                            'res.partner', 
 
1277
                            'res_partner_category_rel', 
 
1278
                            'category_id', 
 
1279
                            'partner_id', 
 
1280
                            'Partners'),
 
1281
                    }
 
1282
                res_partner_category2()
 
1283
 
 
1284
.. i18n: :related:
 
1285
..
 
1286
 
 
1287
:related:
 
1288
 
 
1289
.. i18n:   Sometimes you need to refer to the relation of a relation. For example,
 
1290
.. i18n:   supposing you have objects: City -> State -> Country, and you need to refer to
 
1291
.. i18n:   the Country from a City, you can define a field as below in the City object::
 
1292
.. i18n: 
 
1293
.. i18n:         'country_id': fields.related(
 
1294
.. i18n:             'state_id', 
 
1295
.. i18n:             'country_id', 
 
1296
.. i18n:             type="many2one",
 
1297
.. i18n:             relation="res.country",
 
1298
.. i18n:             string="Country", 
 
1299
.. i18n:             store=False)
 
1300
.. i18n: 
 
1301
.. i18n:   Where:
 
1302
.. i18n:        - The first set of parameters are the chain of reference fields to
 
1303
.. i18n:          follow, with the desired field at the end.
 
1304
.. i18n:        - :guilabel:`type` is the type of that desired field.
 
1305
.. i18n:        - Use :guilabel:`relation` if the desired field is still some kind of
 
1306
.. i18n:          reference. :guilabel:`relation` is the table to look up that
 
1307
.. i18n:          reference in.
 
1308
..
 
1309
 
 
1310
  Sometimes you need to refer to the relation of a relation. For example,
 
1311
  supposing you have objects: City -> State -> Country, and you need to refer to
 
1312
  the Country from a City, you can define a field as below in the City object::
 
1313
 
 
1314
        'country_id': fields.related(
 
1315
            'state_id', 
 
1316
            'country_id', 
 
1317
            type="many2one",
 
1318
            relation="res.country",
 
1319
            string="Country", 
 
1320
            store=False)
 
1321
 
 
1322
  Where:
 
1323
        - The first set of parameters are the chain of reference fields to
 
1324
          follow, with the desired field at the end.
 
1325
        - :guilabel:`type` is the type of that desired field.
 
1326
        - Use :guilabel:`relation` if the desired field is still some kind of
 
1327
          reference. :guilabel:`relation` is the table to look up that
 
1328
          reference in.
 
1329
 
 
1330
.. i18n: Functional Fields
 
1331
.. i18n: +++++++++++++++++
 
1332
..
 
1333
 
 
1334
Functional Fields
 
1335
+++++++++++++++++
 
1336
 
 
1337
.. i18n: A functional field is a field whose value is calculated by a function (rather
 
1338
.. i18n: than being stored in the database).
 
1339
..
 
1340
 
 
1341
A functional field is a field whose value is calculated by a function (rather
 
1342
than being stored in the database).
 
1343
 
 
1344
.. i18n: **Parameters:** ::
 
1345
.. i18n: 
 
1346
.. i18n:     fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type="float",
 
1347
.. i18n:         fnct_search=None, obj=None, method=False, store=False, multi=False
 
1348
..
 
1349
 
 
1350
**Parameters:** ::
 
1351
 
 
1352
    fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type="float",
 
1353
        fnct_search=None, obj=None, method=False, store=False, multi=False
 
1354
 
 
1355
.. i18n: where
 
1356
..
 
1357
 
 
1358
where
 
1359
 
 
1360
.. i18n:     * :guilabel:`fnct` is the function or method that will compute the field 
 
1361
.. i18n:       value. It must have been declared before declaring the functional field.
 
1362
.. i18n:     * :guilabel:`fnct_inv` is the function or method that will allow writing
 
1363
.. i18n:       values in that field.
 
1364
.. i18n:     * :guilabel:`type` is the field type name returned by the function. It can
 
1365
.. i18n:       be any field type name except function.
 
1366
.. i18n:     * :guilabel:`fnct_search` allows you to define the searching behaviour on
 
1367
.. i18n:       that field.
 
1368
.. i18n:     * :guilabel:`method` whether the field is computed by a method (of an
 
1369
.. i18n:       object) or a global function
 
1370
.. i18n:     * :guilabel:`store` If you want to store field in database or not. Default
 
1371
.. i18n:       is False.
 
1372
.. i18n:     * :guilabel:`multi` is a group name. All fields with the same `multi`
 
1373
.. i18n:       parameter will be calculated in a single function call. 
 
1374
..
 
1375
 
 
1376
    * :guilabel:`fnct` is the function or method that will compute the field 
 
1377
      value. It must have been declared before declaring the functional field.
 
1378
    * :guilabel:`fnct_inv` is the function or method that will allow writing
 
1379
      values in that field.
 
1380
    * :guilabel:`type` is the field type name returned by the function. It can
 
1381
      be any field type name except function.
 
1382
    * :guilabel:`fnct_search` allows you to define the searching behaviour on
 
1383
      that field.
 
1384
    * :guilabel:`method` whether the field is computed by a method (of an
 
1385
      object) or a global function
 
1386
    * :guilabel:`store` If you want to store field in database or not. Default
 
1387
      is False.
 
1388
    * :guilabel:`multi` is a group name. All fields with the same `multi`
 
1389
      parameter will be calculated in a single function call. 
 
1390
 
 
1391
.. i18n: fnct parameter
 
1392
.. i18n: """"""""""""""
 
1393
.. i18n: If *method* is True, the signature of the method must be::
 
1394
.. i18n: 
 
1395
.. i18n:     def fnct(self, cr, uid, ids, field_name, arg, context):
 
1396
..
 
1397
 
 
1398
fnct parameter
 
1399
""""""""""""""
 
1400
If *method* is True, the signature of the method must be::
 
1401
 
 
1402
    def fnct(self, cr, uid, ids, field_name, arg, context):
 
1403
 
 
1404
.. i18n: otherwise (if it is a global function), its signature must be::
 
1405
.. i18n: 
 
1406
.. i18n:     def fnct(cr, table, ids, field_name, arg, context):
 
1407
..
 
1408
 
 
1409
otherwise (if it is a global function), its signature must be::
 
1410
 
 
1411
    def fnct(cr, table, ids, field_name, arg, context):
 
1412
 
 
1413
.. i18n: Either way, it must return a dictionary of values of the form
 
1414
.. i18n: **{id'_1_': value'_1_', id'_2_': value'_2_',...}.**
 
1415
..
 
1416
 
 
1417
Either way, it must return a dictionary of values of the form
 
1418
**{id'_1_': value'_1_', id'_2_': value'_2_',...}.**
 
1419
 
 
1420
.. i18n: The values of the returned dictionary must be of the type specified by the type 
 
1421
.. i18n: argument in the field declaration.
 
1422
..
 
1423
 
 
1424
The values of the returned dictionary must be of the type specified by the type 
 
1425
argument in the field declaration.
 
1426
 
 
1427
.. i18n: If *multi* is set, then *field_name* is replaced by *field_names*: a list
 
1428
.. i18n: of the field names that should be calculated. Each value in the returned 
 
1429
.. i18n: dictionary is also a dictionary from field name to value. For example, if the
 
1430
.. i18n: fields `'name'`, and `'age'` are both based on the `vital_statistics` function,
 
1431
.. i18n: then the return value of `vital_statistics` might look like this when `ids` is
 
1432
.. i18n: `[1, 2, 5]`::
 
1433
.. i18n: 
 
1434
.. i18n:     {
 
1435
.. i18n:         1: {'name': 'Bob', 'age': 23}, 
 
1436
.. i18n:         2: {'name': 'Sally', 'age', 19}, 
 
1437
.. i18n:         5: {'name': 'Ed', 'age': 62}
 
1438
.. i18n:     }
 
1439
..
 
1440
 
 
1441
If *multi* is set, then *field_name* is replaced by *field_names*: a list
 
1442
of the field names that should be calculated. Each value in the returned 
 
1443
dictionary is also a dictionary from field name to value. For example, if the
 
1444
fields `'name'`, and `'age'` are both based on the `vital_statistics` function,
 
1445
then the return value of `vital_statistics` might look like this when `ids` is
 
1446
`[1, 2, 5]`::
 
1447
 
 
1448
    {
 
1449
        1: {'name': 'Bob', 'age': 23}, 
 
1450
        2: {'name': 'Sally', 'age', 19}, 
 
1451
        5: {'name': 'Ed', 'age': 62}
 
1452
    }
 
1453
 
 
1454
.. i18n: fnct_inv parameter
 
1455
.. i18n: """"""""""""""""""
 
1456
.. i18n: If *method* is true, the signature of the method must be::
 
1457
.. i18n: 
 
1458
.. i18n:     def fnct(self, cr, uid, ids, field_name, field_value, arg, context):
 
1459
.. i18n:     
 
1460
..
 
1461
 
 
1462
fnct_inv parameter
 
1463
""""""""""""""""""
 
1464
If *method* is true, the signature of the method must be::
 
1465
 
 
1466
    def fnct(self, cr, uid, ids, field_name, field_value, arg, context):
 
1467
    
 
1468
 
 
1469
.. i18n: otherwise (if it is a global function), it should be::
 
1470
.. i18n: 
 
1471
.. i18n:     def fnct(cr, table, ids, field_name, field_value, arg, context):
 
1472
..
 
1473
 
 
1474
otherwise (if it is a global function), it should be::
 
1475
 
 
1476
    def fnct(cr, table, ids, field_name, field_value, arg, context):
 
1477
 
 
1478
.. i18n: fnct_search parameter
 
1479
.. i18n: """""""""""""""""""""
 
1480
.. i18n: If method is true, the signature of the method must be::
 
1481
.. i18n: 
 
1482
.. i18n:     def fnct(self, cr, uid, obj, name, args, context):
 
1483
..
 
1484
 
 
1485
fnct_search parameter
 
1486
"""""""""""""""""""""
 
1487
If method is true, the signature of the method must be::
 
1488
 
 
1489
    def fnct(self, cr, uid, obj, name, args, context):
 
1490
 
 
1491
.. i18n: otherwise (if it is a global function), it should be::
 
1492
.. i18n: 
 
1493
.. i18n:     def fnct(cr, uid, obj, name, args, context):
 
1494
..
 
1495
 
 
1496
otherwise (if it is a global function), it should be::
 
1497
 
 
1498
    def fnct(cr, uid, obj, name, args, context):
 
1499
 
 
1500
.. i18n: The return value is a list containing 3-part tuples which are used in search function::
 
1501
.. i18n: 
 
1502
.. i18n:     return [('id','in',[1,3,5])]
 
1503
..
 
1504
 
 
1505
The return value is a list containing 3-part tuples which are used in search function::
 
1506
 
 
1507
    return [('id','in',[1,3,5])]
 
1508
 
 
1509
.. i18n: *obj* is the same as *self*, and *name* receives the field name. *args* is a list
 
1510
.. i18n: of 3-part tuples containing search criteria for this field, although the search
 
1511
.. i18n: function may be called separately for each tuple.
 
1512
..
 
1513
 
 
1514
*obj* is the same as *self*, and *name* receives the field name. *args* is a list
 
1515
of 3-part tuples containing search criteria for this field, although the search
 
1516
function may be called separately for each tuple.
 
1517
 
 
1518
.. i18n: Example
 
1519
.. i18n: """""""
 
1520
.. i18n: Suppose we create a contract object which is :
 
1521
..
 
1522
 
 
1523
Example
 
1524
"""""""
 
1525
Suppose we create a contract object which is :
 
1526
 
 
1527
.. i18n: .. code-block:: python
 
1528
.. i18n: 
 
1529
.. i18n:     class hr_contract(osv.osv):
 
1530
.. i18n:         _name = 'hr.contract'
 
1531
.. i18n:         _description = 'Contract'
 
1532
.. i18n:         _columns = {
 
1533
.. i18n:             'name' : fields.char('Contract Name', size=30, required=True),
 
1534
.. i18n:             'employee_id' : fields.many2one('hr.employee', 'Employee', required=True),
 
1535
.. i18n:             'function' : fields.many2one('res.partner.function', 'Function'),
 
1536
.. i18n:         }
 
1537
.. i18n:     hr_contract()
 
1538
..
 
1539
 
 
1540
.. code-block:: python
 
1541
 
 
1542
    class hr_contract(osv.osv):
 
1543
        _name = 'hr.contract'
 
1544
        _description = 'Contract'
 
1545
        _columns = {
 
1546
            'name' : fields.char('Contract Name', size=30, required=True),
 
1547
            'employee_id' : fields.many2one('hr.employee', 'Employee', required=True),
 
1548
            'function' : fields.many2one('res.partner.function', 'Function'),
 
1549
        }
 
1550
    hr_contract()
 
1551
 
 
1552
.. i18n: If we want to add a field that retrieves the function of an employee by looking its current contract, we use a functional field. The object hr_employee is inherited this way:
 
1553
..
 
1554
 
 
1555
If we want to add a field that retrieves the function of an employee by looking its current contract, we use a functional field. The object hr_employee is inherited this way:
 
1556
 
 
1557
.. i18n: .. code-block:: python
 
1558
.. i18n: 
 
1559
.. i18n:     class hr_employee(osv.osv):
 
1560
.. i18n:         _name = "hr.employee"
 
1561
.. i18n:         _description = "Employee"
 
1562
.. i18n:         _inherit = "hr.employee"
 
1563
.. i18n:         _columns = {
 
1564
.. i18n:             'contract_ids' : fields.one2many('hr.contract', 'employee_id', 'Contracts'),
 
1565
.. i18n:             'function' : fields.function(
 
1566
.. i18n:                 _get_cur_function_id, 
 
1567
.. i18n:                 type='many2one', 
 
1568
.. i18n:                 obj="res.partner.function",
 
1569
.. i18n:                 method=True, 
 
1570
.. i18n:                 string='Contract Function'),
 
1571
.. i18n:         }
 
1572
.. i18n:     hr_employee()
 
1573
..
 
1574
 
 
1575
.. code-block:: python
 
1576
 
 
1577
    class hr_employee(osv.osv):
 
1578
        _name = "hr.employee"
 
1579
        _description = "Employee"
 
1580
        _inherit = "hr.employee"
 
1581
        _columns = {
 
1582
            'contract_ids' : fields.one2many('hr.contract', 'employee_id', 'Contracts'),
 
1583
            'function' : fields.function(
 
1584
                _get_cur_function_id, 
 
1585
                type='many2one', 
 
1586
                obj="res.partner.function",
 
1587
                method=True, 
 
1588
                string='Contract Function'),
 
1589
        }
 
1590
    hr_employee()
 
1591
 
 
1592
.. i18n: .. note:: three points
 
1593
.. i18n: 
 
1594
.. i18n:         * :guilabel:`type` ='many2one' is because the function field must create
 
1595
.. i18n:           a many2one field; function is declared as a many2one in hr_contract also.
 
1596
.. i18n:         * :guilabel:`obj` ="res.partner.function" is used to specify that the
 
1597
.. i18n:           object to use for the many2one field is res.partner.function.
 
1598
.. i18n:         * We called our method :guilabel:`_get_cur_function_id` because its role
 
1599
.. i18n:           is to return a dictionary whose keys are ids of employees, and whose
 
1600
.. i18n:           corresponding values are ids of the function of those employees. The 
 
1601
.. i18n:           code of this method is:
 
1602
..
 
1603
 
 
1604
.. note:: three points
 
1605
 
 
1606
        * :guilabel:`type` ='many2one' is because the function field must create
 
1607
          a many2one field; function is declared as a many2one in hr_contract also.
 
1608
        * :guilabel:`obj` ="res.partner.function" is used to specify that the
 
1609
          object to use for the many2one field is res.partner.function.
 
1610
        * We called our method :guilabel:`_get_cur_function_id` because its role
 
1611
          is to return a dictionary whose keys are ids of employees, and whose
 
1612
          corresponding values are ids of the function of those employees. The 
 
1613
          code of this method is:
 
1614
 
 
1615
.. i18n: .. code-block:: python
 
1616
.. i18n: 
 
1617
.. i18n:     def _get_cur_function_id(self, cr, uid, ids, field_name, arg, context):
 
1618
.. i18n:         for i in ids:
 
1619
.. i18n:             #get the id of the current function of the employee of identifier "i"
 
1620
.. i18n:             sql_req= """
 
1621
.. i18n:             SELECT f.id AS func_id
 
1622
.. i18n:             FROM hr_contract c
 
1623
.. i18n:               LEFT JOIN res_partner_function f ON (f.id = c.function)
 
1624
.. i18n:             WHERE
 
1625
.. i18n:               (c.employee_id = %d)
 
1626
.. i18n:             """ % (i,)
 
1627
.. i18n:     
 
1628
.. i18n:             cr.execute(sql_req)
 
1629
.. i18n:             sql_res = cr.dictfetchone()
 
1630
.. i18n:     
 
1631
.. i18n:             if sql_res: #The employee has one associated contract
 
1632
.. i18n:                 res[i] = sql_res['func_id']
 
1633
.. i18n:             else:
 
1634
.. i18n:                 #res[i] must be set to False and not to None because of XML:RPC
 
1635
.. i18n:                 # "cannot marshal None unless allow_none is enabled"
 
1636
.. i18n:                 res[i] = False
 
1637
.. i18n:         return res
 
1638
..
 
1639
 
 
1640
.. code-block:: python
 
1641
 
 
1642
    def _get_cur_function_id(self, cr, uid, ids, field_name, arg, context):
 
1643
        for i in ids:
 
1644
            #get the id of the current function of the employee of identifier "i"
 
1645
            sql_req= """
 
1646
            SELECT f.id AS func_id
 
1647
            FROM hr_contract c
 
1648
              LEFT JOIN res_partner_function f ON (f.id = c.function)
 
1649
            WHERE
 
1650
              (c.employee_id = %d)
 
1651
            """ % (i,)
 
1652
    
 
1653
            cr.execute(sql_req)
 
1654
            sql_res = cr.dictfetchone()
 
1655
    
 
1656
            if sql_res: #The employee has one associated contract
 
1657
                res[i] = sql_res['func_id']
 
1658
            else:
 
1659
                #res[i] must be set to False and not to None because of XML:RPC
 
1660
                # "cannot marshal None unless allow_none is enabled"
 
1661
                res[i] = False
 
1662
        return res
 
1663
 
 
1664
.. i18n: The id of the function is retrieved using a SQL query. Note that if the query 
 
1665
.. i18n: returns no result, the value of sql_res['func_id'] will be None. We force the
 
1666
.. i18n: False value in this case value because XML:RPC (communication between the server 
 
1667
.. i18n: and the client) doesn't allow to transmit this value.
 
1668
..
 
1669
 
 
1670
The id of the function is retrieved using a SQL query. Note that if the query 
 
1671
returns no result, the value of sql_res['func_id'] will be None. We force the
 
1672
False value in this case value because XML:RPC (communication between the server 
 
1673
and the client) doesn't allow to transmit this value.
 
1674
 
 
1675
.. i18n: store Parameter
 
1676
.. i18n: """""""""""""""
 
1677
.. i18n: It will calculate the field and store the result in the table. The field will be
 
1678
.. i18n: recalculated when certain fields are changed on other objects. It uses the
 
1679
.. i18n: following syntax:
 
1680
..
 
1681
 
 
1682
store Parameter
 
1683
"""""""""""""""
 
1684
It will calculate the field and store the result in the table. The field will be
 
1685
recalculated when certain fields are changed on other objects. It uses the
 
1686
following syntax:
 
1687
 
 
1688
.. i18n: .. code-block:: python
 
1689
.. i18n: 
 
1690
.. i18n:     store = {
 
1691
.. i18n:         'object_name': (
 
1692
.. i18n:                function_name, 
 
1693
.. i18n:                ['field_name1', 'field_name2'],
 
1694
.. i18n:                priority)
 
1695
.. i18n:     }
 
1696
..
 
1697
 
 
1698
.. code-block:: python
 
1699
 
 
1700
    store = {
 
1701
        'object_name': (
 
1702
                function_name, 
 
1703
                ['field_name1', 'field_name2'],
 
1704
                priority)
 
1705
    }
 
1706
 
 
1707
.. i18n: It will call function function_name when any changes are written to fields in the
 
1708
.. i18n: list ['field1','field2'] on object 'object_name'. The function should have the
 
1709
.. i18n: following signature::
 
1710
.. i18n: 
 
1711
.. i18n:     def function_name(self, cr, uid, ids, context=None):
 
1712
..
 
1713
 
 
1714
It will call function function_name when any changes are written to fields in the
 
1715
list ['field1','field2'] on object 'object_name'. The function should have the
 
1716
following signature::
 
1717
 
 
1718
    def function_name(self, cr, uid, ids, context=None):
 
1719
 
 
1720
.. i18n: Where `ids` will be the ids of records in the other object's table that have
 
1721
.. i18n: changed values in the watched fields. The function should return a list of ids
 
1722
.. i18n: of records in its own table that should have the field recalculated. That list 
 
1723
.. i18n: will be sent as a parameter for the main function of the field.
 
1724
..
 
1725
 
 
1726
Where `ids` will be the ids of records in the other object's table that have
 
1727
changed values in the watched fields. The function should return a list of ids
 
1728
of records in its own table that should have the field recalculated. That list 
 
1729
will be sent as a parameter for the main function of the field.
 
1730
 
 
1731
.. i18n: Here's an example from the membership module:
 
1732
..
 
1733
 
 
1734
Here's an example from the membership module:
 
1735
 
 
1736
.. i18n: .. code-block:: python
 
1737
.. i18n: 
 
1738
.. i18n:     'membership_state':
 
1739
.. i18n:         fields.function(
 
1740
.. i18n:             _membership_state,
 
1741
.. i18n:             method=True, 
 
1742
.. i18n:             string='Current membership state',
 
1743
.. i18n:             type='selection', 
 
1744
.. i18n:             selection=STATE,
 
1745
.. i18n:             store={
 
1746
.. i18n:                 'account.invoice': (_get_invoice_partner, ['state'], 10),
 
1747
.. i18n:                 'membership.membership_line': (_get_partner_id,['state'], 10),
 
1748
.. i18n:                 'res.partner': (
 
1749
.. i18n:                     lambda self, cr, uid, ids, c={}: ids, 
 
1750
.. i18n:                     ['free_member'], 
 
1751
.. i18n:                     10)
 
1752
.. i18n:             }),
 
1753
..
 
1754
 
 
1755
.. code-block:: python
 
1756
 
 
1757
    'membership_state':
 
1758
        fields.function(
 
1759
            _membership_state,
 
1760
            method=True, 
 
1761
            string='Current membership state',
 
1762
            type='selection', 
 
1763
            selection=STATE,
 
1764
            store={
 
1765
                'account.invoice': (_get_invoice_partner, ['state'], 10),
 
1766
                'membership.membership_line': (_get_partner_id,['state'], 10),
 
1767
                'res.partner': (
 
1768
                    lambda self, cr, uid, ids, c={}: ids, 
 
1769
                    ['free_member'], 
 
1770
                    10)
 
1771
            }),
 
1772
 
 
1773
.. i18n: Property Fields
 
1774
.. i18n: +++++++++++++++
 
1775
..
 
1776
 
 
1777
Property Fields
 
1778
+++++++++++++++
 
1779
 
 
1780
.. i18n: .. describe:: Declaring a property
 
1781
..
 
1782
 
 
1783
.. describe:: Declaring a property
 
1784
 
 
1785
.. i18n: A property is a special field: fields.property.
 
1786
..
 
1787
 
 
1788
A property is a special field: fields.property.
 
1789
 
 
1790
.. i18n: .. code-block:: python
 
1791
.. i18n: 
 
1792
.. i18n:         class res_partner(osv.osv):
 
1793
.. i18n:             _name = "res.partner"
 
1794
.. i18n:             _inherit = "res.partner"
 
1795
.. i18n:             _columns = {
 
1796
.. i18n:                         'property_product_pricelist':
 
1797
.. i18n:                                                    fields.property(
 
1798
.. i18n:                                        'product.pricelist',
 
1799
.. i18n:                                 type='many2one',
 
1800
.. i18n:                                 relation='product.pricelist',
 
1801
.. i18n:                                 string="Sale Pricelist",
 
1802
.. i18n:                                        method=True,
 
1803
.. i18n:                                        view_load=True,
 
1804
.. i18n:                                        group_name="Pricelists Properties"),
 
1805
.. i18n:             }
 
1806
..
 
1807
 
 
1808
.. code-block:: python
 
1809
 
 
1810
        class res_partner(osv.osv):
 
1811
            _name = "res.partner"
 
1812
            _inherit = "res.partner"
 
1813
            _columns = {
 
1814
                        'property_product_pricelist':
 
1815
                                                    fields.property(
 
1816
                                        'product.pricelist',
 
1817
                                type='many2one',
 
1818
                                relation='product.pricelist',
 
1819
                                string="Sale Pricelist",
 
1820
                                        method=True,
 
1821
                                        view_load=True,
 
1822
                                        group_name="Pricelists Properties"),
 
1823
            }
 
1824
 
 
1825
.. i18n: Then you have to create the default value in a .XML file for this property:
 
1826
..
 
1827
 
 
1828
Then you have to create the default value in a .XML file for this property:
 
1829
 
 
1830
.. i18n: .. code-block:: xml
 
1831
.. i18n: 
 
1832
.. i18n:         <record model="ir.property" id="property_product_pricelist">
 
1833
.. i18n:             <field name="name">property_product_pricelist</field>
 
1834
.. i18n:             <field name="fields_id" search="[('model','=','res.partner'),
 
1835
.. i18n:               ('name','=','property_product_pricelist')]"/>
 
1836
.. i18n:             <field name="value" eval="'product.pricelist,'+str(list0)"/>
 
1837
.. i18n:         </record>
 
1838
..
 
1839
 
 
1840
.. code-block:: xml
 
1841
 
 
1842
        <record model="ir.property" id="property_product_pricelist">
 
1843
            <field name="name">property_product_pricelist</field>
 
1844
            <field name="fields_id" search="[('model','=','res.partner'),
 
1845
              ('name','=','property_product_pricelist')]"/>
 
1846
            <field name="value" eval="'product.pricelist,'+str(list0)"/>
 
1847
        </record>
 
1848
 
 
1849
.. i18n: ..
 
1850
..
 
1851
 
 
1852
..
 
1853
 
 
1854
.. i18n: .. tip::
 
1855
.. i18n: 
 
1856
.. i18n:         if the default value points to a resource from another module, you can use the ref function like this:
 
1857
.. i18n: 
 
1858
.. i18n:         <field name="value" eval="'product.pricelist,'+str(ref('module.data_id'))"/>
 
1859
..
 
1860
 
 
1861
.. tip::
 
1862
 
 
1863
        if the default value points to a resource from another module, you can use the ref function like this:
 
1864
 
 
1865
        <field name="value" eval="'product.pricelist,'+str(ref('module.data_id'))"/>
 
1866
 
 
1867
.. i18n: **Putting properties in forms**
 
1868
..
 
1869
 
 
1870
**Putting properties in forms**
 
1871
 
 
1872
.. i18n: To add properties in forms, just put the <properties/> tag in your form. This will automatically add all properties fields that are related to this object. The system will add properties depending on your rights. (some people will be able to change a specific property, others won't).
 
1873
..
 
1874
 
 
1875
To add properties in forms, just put the <properties/> tag in your form. This will automatically add all properties fields that are related to this object. The system will add properties depending on your rights. (some people will be able to change a specific property, others won't).
 
1876
 
 
1877
.. i18n: Properties are displayed by section, depending on the group_name attribute. (It is rendered in the client like a separator tag).
 
1878
..
 
1879
 
 
1880
Properties are displayed by section, depending on the group_name attribute. (It is rendered in the client like a separator tag).
 
1881
 
 
1882
.. i18n: **How does this work ?**
 
1883
..
 
1884
 
 
1885
**How does this work ?**
 
1886
 
 
1887
.. i18n: The fields.property class inherits from fields.function and overrides the read and write method. The type of this field is many2one, so in the form a property is represented like a many2one function.
 
1888
..
 
1889
 
 
1890
The fields.property class inherits from fields.function and overrides the read and write method. The type of this field is many2one, so in the form a property is represented like a many2one function.
 
1891
 
 
1892
.. i18n: But the value of a property is stored in the ir.property class/table as a complete record. The stored value is a field of type reference (not many2one) because each property may point to a different object. If you edit properties values (from the administration menu), these are represented like a field of type reference.
 
1893
..
 
1894
 
 
1895
But the value of a property is stored in the ir.property class/table as a complete record. The stored value is a field of type reference (not many2one) because each property may point to a different object. If you edit properties values (from the administration menu), these are represented like a field of type reference.
 
1896
 
 
1897
.. i18n: When you read a property, the program gives you the property attached to the instance of object you are reading. If this object has no value, the system will give you the default property.
 
1898
..
 
1899
 
 
1900
When you read a property, the program gives you the property attached to the instance of object you are reading. If this object has no value, the system will give you the default property.
 
1901
 
 
1902
.. i18n: The definition of a property is stored in the ir.model.fields class like any other fields. In the definition of the property, you can add groups that are allowed to change to property.
 
1903
..
 
1904
 
 
1905
The definition of a property is stored in the ir.model.fields class like any other fields. In the definition of the property, you can add groups that are allowed to change to property.
 
1906
 
 
1907
.. i18n: **Using properties or normal fields**
 
1908
..
 
1909
 
 
1910
**Using properties or normal fields**
 
1911
 
 
1912
.. i18n: When you want to add a new feature, you will have to choose to implement it as a property or as normal field. Use a normal field when you inherit from an object and want to extend this object. Use a property when the new feature is not related to the object but to an external concept.
 
1913
..
 
1914
 
 
1915
When you want to add a new feature, you will have to choose to implement it as a property or as normal field. Use a normal field when you inherit from an object and want to extend this object. Use a property when the new feature is not related to the object but to an external concept.
 
1916
 
 
1917
.. i18n: Here are a few tips to help you choose between a normal field or a property:
 
1918
..
 
1919
 
 
1920
Here are a few tips to help you choose between a normal field or a property:
 
1921
 
 
1922
.. i18n: Normal fields extend the object, adding more features or data.
 
1923
..
 
1924
 
 
1925
Normal fields extend the object, adding more features or data.
 
1926
 
 
1927
.. i18n: A property is a concept that is attached to an object and have special features:
 
1928
..
 
1929
 
 
1930
A property is a concept that is attached to an object and have special features:
 
1931
 
 
1932
.. i18n: * Different value for the same property depending on the company
 
1933
.. i18n: * Rights management per field
 
1934
.. i18n: * It's a link between resources (many2one)
 
1935
..
 
1936
 
 
1937
* Different value for the same property depending on the company
 
1938
* Rights management per field
 
1939
* It's a link between resources (many2one)
 
1940
 
 
1941
.. i18n: **Example 1: Account Receivable**
 
1942
..
 
1943
 
 
1944
**Example 1: Account Receivable**
 
1945
 
 
1946
.. i18n: The default "Account Receivable" for a specific partner is implemented as a property because:
 
1947
..
 
1948
 
 
1949
The default "Account Receivable" for a specific partner is implemented as a property because:
 
1950
 
 
1951
.. i18n:     * This is a concept related to the account chart and not to the partner, so it is an account property that is visible on a partner form. Rights have to be managed on this fields for accountants, these are not the same rights that are applied to partner objects. So you have specific rights just for this field of the partner form: only accountants may change the account receivable of a partner.
 
1952
.. i18n: 
 
1953
.. i18n:     * This is a multi-company field: the same partner may have different account receivable values depending on the company the user belongs to. In a multi-company system, there is one account chart per company. The account receivable of a partner depends on the company it placed the sale order.
 
1954
.. i18n: 
 
1955
.. i18n:     * The default account receivable is the same for all partners and is configured from the general property menu (in administration).
 
1956
..
 
1957
 
 
1958
    * This is a concept related to the account chart and not to the partner, so it is an account property that is visible on a partner form. Rights have to be managed on this fields for accountants, these are not the same rights that are applied to partner objects. So you have specific rights just for this field of the partner form: only accountants may change the account receivable of a partner.
 
1959
 
 
1960
    * This is a multi-company field: the same partner may have different account receivable values depending on the company the user belongs to. In a multi-company system, there is one account chart per company. The account receivable of a partner depends on the company it placed the sale order.
 
1961
 
 
1962
    * The default account receivable is the same for all partners and is configured from the general property menu (in administration).
 
1963
 
 
1964
.. i18n: .. note::
 
1965
.. i18n:         One interesting thing is that properties avoid "spaghetti" code. The account module depends on the partner (base) module. But you can install the partner (base) module without the accounting module. If you add a field that points to an account in the partner object, both objects will depend on each other. It's much more difficult to maintain and code (for instance, try to remove a table when both tables are pointing to each others.)
 
1966
..
 
1967
 
 
1968
.. note::
 
1969
        One interesting thing is that properties avoid "spaghetti" code. The account module depends on the partner (base) module. But you can install the partner (base) module without the accounting module. If you add a field that points to an account in the partner object, both objects will depend on each other. It's much more difficult to maintain and code (for instance, try to remove a table when both tables are pointing to each others.)
 
1970
 
 
1971
.. i18n: **Example 2: Product Times**
 
1972
..
 
1973
 
 
1974
**Example 2: Product Times**
 
1975
 
 
1976
.. i18n: The product expiry module implements all delays related to products: removal date, product usetime, ... This module is very useful for food industries.
 
1977
..
 
1978
 
 
1979
The product expiry module implements all delays related to products: removal date, product usetime, ... This module is very useful for food industries.
 
1980
 
 
1981
.. i18n: This module inherits from the product.product object and adds new fields to it:
 
1982
..
 
1983
 
 
1984
This module inherits from the product.product object and adds new fields to it:
 
1985
 
 
1986
.. i18n: .. code-block:: python
 
1987
.. i18n: 
 
1988
.. i18n:         class product_product(osv.osv):
 
1989
.. i18n: 
 
1990
.. i18n:             _inherit = 'product.product'
 
1991
.. i18n:             _name = 'product.product'
 
1992
.. i18n:             _columns = {
 
1993
.. i18n: 
 
1994
.. i18n:                 'life_time': fields.integer('Product lifetime'),
 
1995
.. i18n:                 'use_time': fields.integer('Product usetime'),
 
1996
.. i18n:                 'removal_time': fields.integer('Product removal time'),
 
1997
.. i18n:                 'alert_time': fields.integer('Product alert time'),
 
1998
.. i18n:                 }
 
1999
.. i18n: 
 
2000
.. i18n:         product_product()
 
2001
..
 
2002
 
 
2003
.. code-block:: python
 
2004
 
 
2005
        class product_product(osv.osv):
 
2006
 
 
2007
            _inherit = 'product.product'
 
2008
            _name = 'product.product'
 
2009
            _columns = {
 
2010
 
 
2011
                'life_time': fields.integer('Product lifetime'),
 
2012
                'use_time': fields.integer('Product usetime'),
 
2013
                'removal_time': fields.integer('Product removal time'),
 
2014
                'alert_time': fields.integer('Product alert time'),
 
2015
                }
 
2016
 
 
2017
        product_product()
 
2018
 
 
2019
.. i18n: ..
 
2020
..
 
2021
 
 
2022
..
 
2023
 
 
2024
.. i18n: This module adds simple fields to the product.product object. We did not use properties because:
 
2025
..
 
2026
 
 
2027
This module adds simple fields to the product.product object. We did not use properties because:
 
2028
 
 
2029
.. i18n:     * We extend a product, the life_time field is a concept related to a product, not to another object.
 
2030
.. i18n:     * We do not need a right management per field, the different delays are managed by the same people that manage all products.
 
2031
..
 
2032
 
 
2033
    * We extend a product, the life_time field is a concept related to a product, not to another object.
 
2034
    * We do not need a right management per field, the different delays are managed by the same people that manage all products.
 
2035
 
 
2036
.. i18n: ORM methods
 
2037
.. i18n: -----------
 
2038
..
 
2039
 
 
2040
ORM methods
 
2041
-----------
 
2042
 
 
2043
.. i18n: Keeping the context in ORM methods
 
2044
.. i18n: ++++++++++++++++++++++++++++++++++
 
2045
..
 
2046
 
 
2047
Keeping the context in ORM methods
 
2048
++++++++++++++++++++++++++++++++++
 
2049
 
 
2050
.. i18n: In OpenObject, the context holds very important data such as the language in
 
2051
.. i18n: which a document must be written, whether function field needs updating or not,
 
2052
.. i18n: etc.
 
2053
..
 
2054
 
 
2055
In OpenObject, the context holds very important data such as the language in
 
2056
which a document must be written, whether function field needs updating or not,
 
2057
etc.
 
2058
 
 
2059
.. i18n: When calling an ORM method, you will probably already have a context - for
 
2060
.. i18n: example the framework will provide you with one as a parameter of almost 
 
2061
.. i18n: every method.
 
2062
.. i18n: If you do have a context, it is very important that you always pass it through
 
2063
.. i18n: to every single method you call.
 
2064
..
 
2065
 
 
2066
When calling an ORM method, you will probably already have a context - for
 
2067
example the framework will provide you with one as a parameter of almost 
 
2068
every method.
 
2069
If you do have a context, it is very important that you always pass it through
 
2070
to every single method you call.
 
2071
 
 
2072
.. i18n: This rule also applies to writing ORM methods. You should expect to receive a
 
2073
.. i18n: context as parameter, and always pass it through to every other method you call.. 
 
2074
..
 
2075
 
 
2076
This rule also applies to writing ORM methods. You should expect to receive a
 
2077
context as parameter, and always pass it through to every other method you call.. 
 
2078
 
 
2079
.. i18n: ORM methods
 
2080
.. i18n: +++++++++++
 
2081
..
 
2082
 
 
2083
ORM methods
 
2084
+++++++++++
 
2085
 
 
2086
.. i18n: .. automodule:: openerp.osv.orm
 
2087
.. i18n:    :members:
 
2088
.. i18n:    :show-inheritance:
 
2089
..
 
2090
 
 
2091
.. automodule:: openerp.osv.orm
 
2092
   :members:
 
2093
   :show-inheritance: