Using Odoo(about Model)
Table of Contents
1 Summary
This article is about tips, skills, mistakes I have met in the past working time. Odoo is a suite of web based open source business apps.(I copy from the README.md file). It is M-V-C strcture. The old name is Openerp. I use the old API, haven't transer to new API after Odoo 8.0 , developing on pyharm, which is a excellent IDE for python development. This is first article, about "Model".
Enviroment : odoo 8.0, python 2.7.6, postgresql 9.3.9, ubuntu 14.04
2 Config
I download odoo at odoo from github,
let's call it directory odoo-8.0
. Because I use ubuntu, you can find
config file in odoo-8.0/debain/openerp-server.conf
, so I copy this
file to the root dir odoo8.0/
, to configure it on my needs.Such as
follows:
db_host = localhost db_port = 5432 db_user = YourUserName db_password = YourPassword addons_path = addons,YourAddonsPathIfExist
Each time I need to to run server, add script parameters as follows:
Your/Path/To/odoo-8.0/odoo.py --config=Your/Path/To/odoo-8.0/openerp-server.conf
3 Module
ododd use Module to extend its funtion. when you need to ceate a module,
you can create a folder in your addon directory, let's call it
coolmodule
. It needs two initial files : __init__.py
and
__openerp__.py
. As the same for python pakages, you need to include
files or direcotories in __init__.py
. The __openerp__.py
is use to
config the module, as follows:
:::python { 'name': 'YourNameOfModule', 'version': '0.0.1', 'category': 'YourCategory', 'sequence': '19', 'description': """YourDescription""", 'summary': u'YourSummary', 'author': 'YourName', 'website': 'YourWebsite', 'depends': ['base','OtherDependsModules'], 'data': [ 'coolmodule.xml', 'security/ir.model.access.csv', 'security/security.xml', 'wizard/wizard_coolmodule.xml' ], 'installable': True, 'auto_install': False, 'application': True, }
Notice: above
'data: ['coolmodule.xml','security/ir.model.access.csv','security/security.xml','wizard/wizard_coolmodule.xml']
is some view and security files that you want to include in this module.
3.1 Model
Generally, the model file can be named as coolmodule.py
(depends on
you), the view file can be named as coolmodule.xml
. In
coolmodule.py
, you can define model in this way(old api):
:::python from openerp.osv import fields, osv class cool_customer(osv.osv): _name = "cool.customer" _description = "YourDescriptions" def _default_title_id(self, cr, uid, context=None): #some code return title_id _columns = { 'name' : fields.char('Name',required=True), 'datetime': fields.datetime('DateTime'), 'title': fields.many2one('cool.customer.title', 'Title'), 'bank_ids': fields.one2many('cool.customer.bank', 'customer_id', 'Banks'), 'comment': fields.text('Notes'), 'active': fields.boolean('Active'), 'type': fields.selection([('default', 'Default'), ('invoice', 'Invoice'),('delivery', 'Shipping'), ('contact', 'Contact'),('other', 'Other')], 'Address Type',help="SomeHelpText."), 'category_id': fields.many2many('cool.costomer.category','coo_customer_category_rel', 'costomer_id', 'category_id', string='Tags'), #'display_name': fields.function(_display_name, type='char', string='Name', store=_display_name_store_triggers, select=True) } _defaults = { 'datetime':fields.datetime.now, 'active': True, 'type': 'contact', 'title': _default_title_id } class cool_customer_title(osv.osv): _name = 'cool.custmoer.title' _order = 'name' _columns = { 'name': fields.char('Title', required=True, translate=True), 'shortcut': fields.char('Abbreviation', translate=True) } class cool_customer_bank(osv.osv): _name = 'cool.customer.bank' _columns = { 'name': fields.char('Title', required=True, translate=True), 'code': fields.char('Code', size=64, required=True), 'customer_id': fields.many2one('cool.customer', 'Account Owner', ondelete='cascade', select=True) } class cool_customer_category(osv.osv): _name = 'cool.customer.category' _columns = { 'name': fields.char('Category Name', required=True, translate=True), 'customer_ids':fields.many2many('cool.costomer','coo_customer_category_rel', 'category_id', 'customer_id', string='Customers'), }
_name = 'cool.customer'
This defines the name of this model, and the name(cool\customer) of table in database._columns = {...}
This defines the columns of the tablecool_customer
, different types as above. Notes the funtion field is a little complicated, I decide to talk it after this article._defaults = {...}
This defines the default value of columns or fields- colums
'datetime': fields.datetime('DateTime')
This defines the date type, and there is an other tpye calledfileds.date('Datet')
, and you can use'date': fields.date.today
to set the default date to today - columns
'type': fields.selection([('default', 'Default'), ('invoice', 'Invoice'),('delivery', 'Shipping'), ('contact', 'Contact'),('other', 'Other')], 'Address Type',help
"SomeHelpText."),= This defines a select coloums, when you have serverl certain options to pick, you can use this kind of field - many2one relation Just like
'title': fields.many2one('cool.customer.title', 'Title')
to define a many2one relation - many2one relation The one side:
'bank_ids': fields.one2many('cool.customer.bank', 'customer_id', 'Banks')
The many side:'customer_id': fields.many2one('cool.customer', 'Account Owner', ondelete='cascade', select=True)
ondelete='cascade'
: means if the record in one side is delete,what will do to the related many side? Other options are: 'null', default value is 'null' - many2many relation
'category_id': fields.many2many('cool.costomer.category','coo_customer_category_rel', 'costomer_id', 'category_id', string
'Tags'),= Thecool.costomer.category
defines the relation model, thecoo_customer_category_rel
defines the third relation table name between the two models,'category_id', 'customer_id'
definds the columns incoo_customer_category_rel
,notice the order to point right model. You can also not writecoo_customer_category_rel, category_id', 'customer_id
to let odoo name for you, but if you have lots many2many relations, remember to point clearly. - defaults :
'title': _default_title_id
The default value of a field can also be a vale of funtion. Notice the definition of the function (such as_default_title_id
here) should be above the place using it.
3.1.1 Methods: create, search, read, browse, write, unlink
- create : when you need create a record, call this method, in this
format:
obj.create(cr, uid, vals, context=context)
vals
is a python dictionary format such as{'name': YourName,'title':2,...}
- obj is object or the model you want to create the record in. You
can get obj like this:
obj = self.pool.get('cool.customer')
. - The method returns the id of new record. If create unsucessfully, odoo will report error message.
- search : this method is use to search the id(s) of given condition,
like
obj.search(cr, uid, domain,context=context)
domain
is a list of tuple, which is some like `[('FieldName1','',Value1),('FieldName2','!
',Value2)]``- This method returns a list of ids it finds, or a emppty list if no record finds.
- read: this method is use to get a list of records of given fields.For
example,
obj.read(cr,uid,ids,['fields1','fields2',...],context=context)
- ids
is a list of ids of records that you want to operate -
'fields1','fields2',...
is fields or columns that you want to read,
According to my previous project, it also add column id
in the return
fields. If you don't specific any field, it will read all the fields. -
This method return something like this:
[{'id':1,fields1': value1,'fields2': value2,...}, {...}, ...]
- browse: It is use to get a specific instance of object. For example,
you can use
obj = self.pool.get('cool.customer')
to get a object(or in java terms,a class) of 'cool.customer', and useinstance_obj = obj.browse(cr,uid,ids,context=context)
to get specific ids of objs. It just like 'class' and 'instance' relations (in java terms). Or maybe, call the value ofself.pool.get('cool.customer')'
'class' is more accurate. The advantage is you can use such asinstance_obj.name
to get the name of this specific object. - write: This method is use to change values of specific records.
Format:
obj.write(cr,uid,ids,vals,context)
ids
is a list of ids you want to changevals
is a python dictionary, like{'FieldName1':vale1,'FieldName2':value2,...}
, Notice,if your Filed is one2many type, just like example field above:bank_ids
, the value is a list of tuple, depends on different change ways, tuple format is different. And if this field is many2many type,the tuple is also different,like follows::::python ##one2many #Add new record (0, 0,{ values }) #update the record which id equals ID (1,ID,{values}) #Delete the record which id equals ID (2,ID) ##many2many #Add new record (0, 0,{ values }) #update the record which id equals ID (1,ID,{values}) #Delete the record which id equals ID (call unlink method) (2,ID) #Cut off relationship, but leave the data (3,ID) #Link the relation of record which id equals ID (4,ID) #Cut off all relations (5) #Cut off all relations and Use records in IDs to replace #This is confusing :(, I will add examples in the following articles (6,0,[IDs])
- This method returns True or raise exception
- unlink : This method is use to delete record(s), format:
obj.unlink(cr,uid,ids,context)
ids
is a list of ids of records you want to delete- This method returns True or raise exception
Notice:
- if you use instanceofobject, in other words, you use the
obj getting from methods browse
, no need to write "cr, uid" or "ids"
due to conditions.
- We can also rewrite the model's "write", "create"
or other function. This will be talk about later
3.1.2 Methods: defaultget, defaultset
To be continue here:)
3.1.3 Error Info for User
raise osv.except_osv(_('Error!'), _('Error Message.'))