SlideShare une entreprise Scribd logo
1  sur  30
Télécharger pour lire hors ligne
From V7 to V8: The New API
Raphael Collet (rco@odoo.com)
Goal
Make the model API
more object-oriented
more Pythonic
less cluttered
From V7 to V8
compatibility: V7 and V8 APIs are interoperable
·
·
·
·
Agenda
Recordsets
Methods
Environment
Fields
Migrating Modules
·
·
·
·
·
Recordsets
Programming with
Recordsets
A recordsetrecordset is:
an ordered collection of records
one concept to replace
browse records,
browse lists,
browse nulls.
an instance of the model's class
·
·
·
·
·
·
The recordset as a collection
It implements sequence and set operations:
partners == env[['res.partner']]..search([])([])
forfor partner inin partners::
assertassert partner inin partners
printprint partner..name
ifif len((partners)) >=>= 55::
fifth == partners[[44]]
extremes == partners[:[:1010]] ++ partners[[--1010:]:]
union == partners1 || partners2
intersection == partners1 && partners2
difference == partners1 -- partners2
The recordset as a record
It behaves just like former browse records:
printprint partner..name
printprint partner[['name']]
printprint partner..parent_id..company_id..name
Except that updates are written to database:
partner..name == 'Agrolait'
partner..email == 'info@agrolait.com'
partner..parent_id == ...... # another record
The recordset as a record
If len(partners) > 1, do it on the firstfirst record:
printprint partners..name # name of first partner
printprint partners[[00]]..name
partners..name == 'Agrolait' # assign first partner
partners[[00]]..name == 'Agrolait'
If len(partners) == 0, return the null value of the field:
printprint partners..name # False
printprint partners..parent_id # empty recordset
partners..name == 'Foo' # ERROR
The recordset as an instance
Methods of the model's class can be invoked on recordsets:
# calling convention: leave out cr, uid, ids, context
@api.multi@api.multi
defdef write((self,, values):):
result == super((C,, self))..write((values))
# search returns a recordset instead of a list of ids
domain == [([('id',, 'in',, self..ids),), (('parent_id',, '=',, False)])]
roots == self..search((domain))
# modify all records in roots
roots..write({({'modified':: True})})
returnreturn result
The missing parameters are hidden inside the recordset.
Methods
Method decorators
Decorators enable support of bothboth old and new API:
fromfrom odoo importimport Model,, api
classclass stuff((Model):):
@api.model@api.model
defdef create((self,, values):):
# self is a recordset, but its content is unused
......
This method definition is equivalent to:
classclass stuff((Model):):
defdef create((self,, cr,, uid,, values,, context==None):):
# self is not a recordset
......
Method decorators
fromfrom odoo importimport Model,, api
classclass stuff((Model):):
@api.multi@api.multi
defdef write((self,, values):):
# self is a recordset and its content is used
# update self.ids
......
This method definition is equivalent to:
classclass stuff((Model):):
defdef multi((self,, cr,, uid,, ids,, values,, context==None):):
# self is not a recordset
......
Method decorators
One-by-one or "autoloop" decorator:
fromfrom odoo importimport Model,, api
classclass stuff((Model):):
@api.one@api.one
defdef cancel((self):):
self..state == 'cancel'
When invoked, the method is applied on every record:
recs..cancel()() # [rec.cancel() for rec in recs]
Method decorators
Methods that return a recordset instead of ids:
fromfrom odoo importimport Model,, api
classclass stuff((Model):):
@api.multi@api.multi
@api.returns@api.returns(('res.partner'))
defdef root_partner((self):):
p == self..partner_id
whilewhile p..parent_id::
p == p..parent_id
returnreturn p
When called with the old API, it returns ids:
roots == recs..root_partner()()
root_ids == model..root_partner((cr,, uid,, ids,, context==None))
Environment: cr, uid, context
The environment object
Encapsulates cr, uid, context:
# recs.env encapsulates cr, uid, context
recs..env..cr # shortcut: recs._cr
recs..env..uid # shortcut: recs._uid
recs..env..context # shortcut: recs._context
# recs.env also provides helpers
recs..env..user # uid as a record
recs..env..ref(('base.group_user')) # resolve xml id
recs..env[['res.partner']] # access to new-API model
The environment object
Switching environments:
# rebrowse recs with different parameters
env2 == recs..env((cr2,, uid2,, context2))
recs2 == recs..with_env((env2))
# special case: change/extend the context
recs2 == recs..with_context((context2))
recs2 == recs..with_context((lang=='fr')) # kwargs extend current context
# special case: change the uid
recs2 == recs..sudo((user))
recs2 == recs..sudo()() # uid = SUPERUSER_ID
Fields
Fields as descriptors
Python descriptors provide getter/setter (like property):
fromfrom odoo importimport Model,, fields
classclass res_partner((Model):):
_name == 'res.partner'
name == fields..Char((required==True))
parent_id == fields..Many2one(('res.partner',, string=='Parent'))
Computed fields
Regular fields with the name of the compute method:
classclass res_partner((Model):):
......
display_name == fields..Char((
string=='Name',, compute=='_compute_display_name',,
))
@api.one@api.one
@api.depends@api.depends(('name',, 'parent_id.name'))
defdef _compute_display_name((self):):
names == [[self..parent_id..name,, self..name]]
self..display_name == ' / '..join((filter((None,, names))))
Computed fields
The compute method must assign field(s) on records:
untaxed == fields..Float((compute=='_amounts'))
taxes == fields..Float((compute=='_amounts'))
total == fields..Float((compute=='_amounts'))
@api.multi@api.multi
@api.depends@api.depends(('lines.amount',, 'lines.taxes'))
defdef _amounts((self):):
forfor order inin self::
order..untaxed == sum((line..amount forfor line inin order..lines))
order..taxes == sum((line..taxes forfor line inin order..lines))
order..total == order..untaxed ++ order..taxes
Computed fields
Stored computed fields are much easier now:
display_name == fields..Char((
string=='Name',, compute=='_compute_display_name',, store==True,,
))
@api.one@api.one
@api.depends@api.depends(('name',, 'parent_id.name'))
defdef _compute_display_name((self):):
......
Field dependencies (@depends) are used for
cache invalidation,
recomputation,
onchange.
·
·
·
Fields with inverse
On may also provide inverseinverse and searchsearch methods:
classclass stuff((Model):):
name == fields..Char()()
loud == fields..Char((
store==False,, compute=='_compute_loud',,
inverse=='_inverse_loud',, search=='_search_loud',,
))
@api.one@api.one
@api.depends@api.depends(('name'))
defdef _compute_loud((self):):
self..loud == ((self..name oror ''))..upper()()
......
Fields with inverse
classclass stuff((Model):):
name == fields..Char()()
loud == fields..Char((
store==False,, compute=='_compute_loud',,
inverse=='_inverse_loud',, search=='_search_loud',,
))
......
@api.one@api.one
defdef _inverse_loud((self):):
self..name == ((self..loud oror ''))..lower()()
defdef _search_loud((self,, operator,, value):):
ifif value isis notnot False::
value == value..lower()()
returnreturn [([('name',, operator,, value)])]
Onchange methods
For computed fields: nothing to do!nothing to do!
For other fields: API is similar to compute methods:
@api.onchange@api.onchange(('partner_id'))
defdef _onchange_partner((self):):
ifif self..partner_id::
self..delivery_id == self..partner_id
The record self is a virtual record:
all form values are set on self
assigned values are not written to database but
returned to the client
·
·
Onchange methods
A field element on a form is automaticallyautomatically decorated with
on_change="1":
if it has an onchange method
if it is a dependency of a computed field
This mechanism may be prevented by explicitly decorating
a field element with on_change="0".
·
·
Python constraints
Similar API, with a specific decorator:
@api.one@api.one
@api.constrains@api.constrains(('lines',, 'max_lines'))
defdef _check_size((self):):
ifif len((self..lines)) >> self..max_lines::
raiseraise WarningWarning((_(("Too many lines in %s")) %% self..name))
The error message is provided by the exception.
Migrating Modules
Guidelines
Do the migration step-by-step:
1. migrate field definitions
rewrite compute methods
2. migrate methods
rely on interoperability
use decorators, they are necessary
3. rewrite onchange methods (incompatible API)
beware of overridden methods!
·
·
·
·
From V7 to V8: The New API
Thanks!

Contenu connexe

Tendances

Tendances (20)

Django Tutorial | Django Web Development With Python | Django Training and Ce...
Django Tutorial | Django Web Development With Python | Django Training and Ce...Django Tutorial | Django Web Development With Python | Django Training and Ce...
Django Tutorial | Django Web Development With Python | Django Training and Ce...
 
Odoo Experience 2018 - Visualizing Data in Odoo: How to Create a New View
Odoo Experience 2018 - Visualizing Data in Odoo: How to Create a New ViewOdoo Experience 2018 - Visualizing Data in Odoo: How to Create a New View
Odoo Experience 2018 - Visualizing Data in Odoo: How to Create a New View
 
Tutorial: Develop an App with the Odoo Framework
Tutorial: Develop an App with the Odoo FrameworkTutorial: Develop an App with the Odoo Framework
Tutorial: Develop an App with the Odoo Framework
 
Odoo - Backend modules in v8
Odoo - Backend modules in v8Odoo - Backend modules in v8
Odoo - Backend modules in v8
 
Discover GraphQL with Python, Graphene and Odoo
Discover GraphQL with Python, Graphene and OdooDiscover GraphQL with Python, Graphene and Odoo
Discover GraphQL with Python, Graphene and Odoo
 
The Odoo JS Framework
The Odoo JS FrameworkThe Odoo JS Framework
The Odoo JS Framework
 
Odoo Experience 2018 - The Odoo JS Framework
Odoo Experience 2018 - The Odoo JS FrameworkOdoo Experience 2018 - The Odoo JS Framework
Odoo Experience 2018 - The Odoo JS Framework
 
Developing New Widgets for your Views in Owl
Developing New Widgets for your Views in OwlDeveloping New Widgets for your Views in Owl
Developing New Widgets for your Views in Owl
 
Django - Python MVC Framework
Django - Python MVC FrameworkDjango - Python MVC Framework
Django - Python MVC Framework
 
HOW TO CREATE A MODULE IN ODOO
HOW TO CREATE A MODULE IN ODOOHOW TO CREATE A MODULE IN ODOO
HOW TO CREATE A MODULE IN ODOO
 
Angular 2.0 Dependency injection
Angular 2.0 Dependency injectionAngular 2.0 Dependency injection
Angular 2.0 Dependency injection
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP Functions
 
Django
DjangoDjango
Django
 
Budget Control with mis_builder 3 (2017)
Budget Control with mis_builder 3 (2017)Budget Control with mis_builder 3 (2017)
Budget Control with mis_builder 3 (2017)
 
Odoo - Smart buttons
Odoo - Smart buttonsOdoo - Smart buttons
Odoo - Smart buttons
 
Quick flask an intro to flask
Quick flask   an intro to flaskQuick flask   an intro to flask
Quick flask an intro to flask
 
Odoo Experience 2018 - Inherit from These 10 Mixins to Empower Your App
Odoo Experience 2018 - Inherit from These 10 Mixins to Empower Your AppOdoo Experience 2018 - Inherit from These 10 Mixins to Empower Your App
Odoo Experience 2018 - Inherit from These 10 Mixins to Empower Your App
 
jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...
jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...
jQuery Tutorial For Beginners | Developing User Interface (UI) Using jQuery |...
 
Set Default Values to Fields in Odoo 15
Set Default Values to Fields in Odoo 15Set Default Values to Fields in Odoo 15
Set Default Values to Fields in Odoo 15
 
Express JS
Express JSExpress JS
Express JS
 

En vedette

Odoo - Open Source CMS: A performance comparision
Odoo - Open Source CMS: A performance comparisionOdoo - Open Source CMS: A performance comparision
Odoo - Open Source CMS: A performance comparision
Odoo
 
Odoo - How to create awesome websites and e-commerce
Odoo - How to create awesome websites and e-commerceOdoo - How to create awesome websites and e-commerce
Odoo - How to create awesome websites and e-commerce
Odoo
 
Odoo - Easily Reconcile your Invoices & Payments with the Brand New Bank Stat...
Odoo - Easily Reconcile your Invoices & Payments with the Brand New Bank Stat...Odoo - Easily Reconcile your Invoices & Payments with the Brand New Bank Stat...
Odoo - Easily Reconcile your Invoices & Payments with the Brand New Bank Stat...
Odoo
 
Odoo - Presentation documentation v8
Odoo - Presentation documentation v8Odoo - Presentation documentation v8
Odoo - Presentation documentation v8
Odoo
 
Odoo - CMS dynamic widgets
Odoo - CMS dynamic widgetsOdoo - CMS dynamic widgets
Odoo - CMS dynamic widgets
Odoo
 
Launching your Odoo SaaS offer
Launching your Odoo SaaS offerLaunching your Odoo SaaS offer
Launching your Odoo SaaS offer
Odoo
 
Discover Odoo POS in v8: your shop ready to use in 20 min
Discover Odoo POS in v8: your shop ready to use in 20 minDiscover Odoo POS in v8: your shop ready to use in 20 min
Discover Odoo POS in v8: your shop ready to use in 20 min
Odoo
 

En vedette (20)

Odoo (OpenERP) - Creating a module
Odoo (OpenERP) - Creating a moduleOdoo (OpenERP) - Creating a module
Odoo (OpenERP) - Creating a module
 
Improving the performance of Odoo deployments
Improving the performance of Odoo deploymentsImproving the performance of Odoo deployments
Improving the performance of Odoo deployments
 
Development Odoo Basic
Development Odoo BasicDevelopment Odoo Basic
Development Odoo Basic
 
Odoo - Open Source CMS: A performance comparision
Odoo - Open Source CMS: A performance comparisionOdoo - Open Source CMS: A performance comparision
Odoo - Open Source CMS: A performance comparision
 
Odoo - Business intelligence: Develop cube views for your own objects
Odoo - Business intelligence: Develop cube views for your own objectsOdoo - Business intelligence: Develop cube views for your own objects
Odoo - Business intelligence: Develop cube views for your own objects
 
Odoo 2016 - Retrospective
Odoo 2016 - RetrospectiveOdoo 2016 - Retrospective
Odoo 2016 - Retrospective
 
Odoo training 2016 - Apagen Solutions Pvt. ltd.
Odoo training 2016 - Apagen Solutions Pvt. ltd.Odoo training 2016 - Apagen Solutions Pvt. ltd.
Odoo training 2016 - Apagen Solutions Pvt. ltd.
 
Odoo - How to create awesome websites and e-commerce
Odoo - How to create awesome websites and e-commerceOdoo - How to create awesome websites and e-commerce
Odoo - How to create awesome websites and e-commerce
 
Odoo - Easily Reconcile your Invoices & Payments with the Brand New Bank Stat...
Odoo - Easily Reconcile your Invoices & Payments with the Brand New Bank Stat...Odoo - Easily Reconcile your Invoices & Payments with the Brand New Bank Stat...
Odoo - Easily Reconcile your Invoices & Payments with the Brand New Bank Stat...
 
Modul Odoo ERP
Modul Odoo ERPModul Odoo ERP
Modul Odoo ERP
 
Odoo - Features and configuration of your Odoo Point of Sale
Odoo - Features and configuration of your Odoo Point of SaleOdoo - Features and configuration of your Odoo Point of Sale
Odoo - Features and configuration of your Odoo Point of Sale
 
Odoo - Presentation documentation v8
Odoo - Presentation documentation v8Odoo - Presentation documentation v8
Odoo - Presentation documentation v8
 
Odoo acces rights & groups
Odoo acces rights & groupsOdoo acces rights & groups
Odoo acces rights & groups
 
Odoo - CMS dynamic widgets
Odoo - CMS dynamic widgetsOdoo - CMS dynamic widgets
Odoo - CMS dynamic widgets
 
Odoo How to - Session - 1
Odoo  How to - Session - 1Odoo  How to - Session - 1
Odoo How to - Session - 1
 
Launching your Odoo SaaS offer
Launching your Odoo SaaS offerLaunching your Odoo SaaS offer
Launching your Odoo SaaS offer
 
Odoo Online platform: architecture and challenges
Odoo Online platform: architecture and challengesOdoo Online platform: architecture and challenges
Odoo Online platform: architecture and challenges
 
Odoo Warehouse Management
Odoo Warehouse ManagementOdoo Warehouse Management
Odoo Warehouse Management
 
Discover Odoo POS in v8: your shop ready to use in 20 min
Discover Odoo POS in v8: your shop ready to use in 20 minDiscover Odoo POS in v8: your shop ready to use in 20 min
Discover Odoo POS in v8: your shop ready to use in 20 min
 
How to manage a service company with Odoo
How to manage a service company with OdooHow to manage a service company with Odoo
How to manage a service company with Odoo
 

Similaire à Odoo - From v7 to v8: the new api

第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource
Kaz Watanabe
 
Presentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERPPresentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERP
Odoo
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
An Overview Of Python With Functional Programming
An Overview Of Python With Functional ProgrammingAn Overview Of Python With Functional Programming
An Overview Of Python With Functional Programming
Adam Getchell
 

Similaire à Odoo - From v7 to v8: the new api (20)

Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource第49回Php勉強会@関東 Datasource
第49回Php勉強会@関東 Datasource
 
Method and decorator
Method and decoratorMethod and decorator
Method and decorator
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end Framework
 
Presentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERPPresentation of the new OpenERP API. Raphael Collet, OpenERP
Presentation of the new OpenERP API. Raphael Collet, OpenERP
 
Refactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and PatternsRefactoring @ Mindvalley: Smells, Techniques and Patterns
Refactoring @ Mindvalley: Smells, Techniques and Patterns
 
TensorFlow local Python XLA client
TensorFlow local Python XLA clientTensorFlow local Python XLA client
TensorFlow local Python XLA client
 
Python-for-Data-Analysis.pptx
Python-for-Data-Analysis.pptxPython-for-Data-Analysis.pptx
Python-for-Data-Analysis.pptx
 
Crafting [Better] API Clients
Crafting [Better] API ClientsCrafting [Better] API Clients
Crafting [Better] API Clients
 
Design Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron PattersonDesign Summit - Rails 4 Migration - Aaron Patterson
Design Summit - Rails 4 Migration - Aaron Patterson
 
Parallel and Async Programming With C#
Parallel and Async Programming With C#Parallel and Async Programming With C#
Parallel and Async Programming With C#
 
SCALA - Functional domain
SCALA -  Functional domainSCALA -  Functional domain
SCALA - Functional domain
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
 
Apache Spark in your likeness - low and high level customization
Apache Spark in your likeness - low and high level customizationApache Spark in your likeness - low and high level customization
Apache Spark in your likeness - low and high level customization
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
An Overview Of Python With Functional Programming
An Overview Of Python With Functional ProgrammingAn Overview Of Python With Functional Programming
An Overview Of Python With Functional Programming
 
Template rendering in rails
Template rendering in rails Template rendering in rails
Template rendering in rails
 
Webinar - Office 365 & PowerShell : A Match Made in Heaven
Webinar - Office 365 & PowerShell : A Match Made in HeavenWebinar - Office 365 & PowerShell : A Match Made in Heaven
Webinar - Office 365 & PowerShell : A Match Made in Heaven
 

Plus de Odoo

Plus de Odoo (20)

Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!Timesheet Workshop: The Timesheet App People Love!
Timesheet Workshop: The Timesheet App People Love!
 
Odoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-ViewerOdoo 3D Product View with Google Model-Viewer
Odoo 3D Product View with Google Model-Viewer
 
Keynote - Vision & Strategy
Keynote - Vision & StrategyKeynote - Vision & Strategy
Keynote - Vision & Strategy
 
Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14Opening Keynote - Unveilling Odoo 14
Opening Keynote - Unveilling Odoo 14
 
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting CapabilityExtending Odoo with a Comprehensive Budgeting and Forecasting Capability
Extending Odoo with a Comprehensive Budgeting and Forecasting Capability
 
Managing Multi-channel Selling with Odoo
Managing Multi-channel Selling with OdooManaging Multi-channel Selling with Odoo
Managing Multi-channel Selling with Odoo
 
Product Configurator: Advanced Use Case
Product Configurator: Advanced Use CaseProduct Configurator: Advanced Use Case
Product Configurator: Advanced Use Case
 
Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?Accounting Automation: How Much Money We Saved and How?
Accounting Automation: How Much Money We Saved and How?
 
Rock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced OperationsRock Your Logistics with Advanced Operations
Rock Your Logistics with Advanced Operations
 
Transition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organizationTransition from a cost to a flow-centric organization
Transition from a cost to a flow-centric organization
 
Synchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the CrisisSynchronization: The Supply Chain Response to Overcome the Crisis
Synchronization: The Supply Chain Response to Overcome the Crisis
 
Running a University with Odoo
Running a University with OdooRunning a University with Odoo
Running a University with Odoo
 
Down Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in OdooDown Payments on Purchase Orders in Odoo
Down Payments on Purchase Orders in Odoo
 
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach foodOdoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
Odoo Implementation in Phases - Success Story of a Retail Chain 3Sach food
 
Migration from Salesforce to Odoo
Migration from Salesforce to OdooMigration from Salesforce to Odoo
Migration from Salesforce to Odoo
 
Preventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine LearningPreventing User Mistakes by Using Machine Learning
Preventing User Mistakes by Using Machine Learning
 
Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification Becoming an Odoo Expert: How to Prepare for the Certification
Becoming an Odoo Expert: How to Prepare for the Certification
 
Instant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping LabelInstant Printing of any Odoo Report or Shipping Label
Instant Printing of any Odoo Report or Shipping Label
 
How Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 FoldHow Odoo helped an Organization Grow 3 Fold
How Odoo helped an Organization Grow 3 Fold
 
From Shopify to Odoo
From Shopify to OdooFrom Shopify to Odoo
From Shopify to Odoo
 

Dernier

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 

Dernier (20)

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 

Odoo - From v7 to v8: the new api

  • 1. From V7 to V8: The New API Raphael Collet (rco@odoo.com)
  • 2. Goal Make the model API more object-oriented more Pythonic less cluttered From V7 to V8 compatibility: V7 and V8 APIs are interoperable · · · ·
  • 5. Programming with Recordsets A recordsetrecordset is: an ordered collection of records one concept to replace browse records, browse lists, browse nulls. an instance of the model's class · · · · · ·
  • 6. The recordset as a collection It implements sequence and set operations: partners == env[['res.partner']]..search([])([]) forfor partner inin partners:: assertassert partner inin partners printprint partner..name ifif len((partners)) >=>= 55:: fifth == partners[[44]] extremes == partners[:[:1010]] ++ partners[[--1010:]:] union == partners1 || partners2 intersection == partners1 && partners2 difference == partners1 -- partners2
  • 7. The recordset as a record It behaves just like former browse records: printprint partner..name printprint partner[['name']] printprint partner..parent_id..company_id..name Except that updates are written to database: partner..name == 'Agrolait' partner..email == 'info@agrolait.com' partner..parent_id == ...... # another record
  • 8. The recordset as a record If len(partners) > 1, do it on the firstfirst record: printprint partners..name # name of first partner printprint partners[[00]]..name partners..name == 'Agrolait' # assign first partner partners[[00]]..name == 'Agrolait' If len(partners) == 0, return the null value of the field: printprint partners..name # False printprint partners..parent_id # empty recordset partners..name == 'Foo' # ERROR
  • 9. The recordset as an instance Methods of the model's class can be invoked on recordsets: # calling convention: leave out cr, uid, ids, context @api.multi@api.multi defdef write((self,, values):): result == super((C,, self))..write((values)) # search returns a recordset instead of a list of ids domain == [([('id',, 'in',, self..ids),), (('parent_id',, '=',, False)])] roots == self..search((domain)) # modify all records in roots roots..write({({'modified':: True})}) returnreturn result The missing parameters are hidden inside the recordset.
  • 11. Method decorators Decorators enable support of bothboth old and new API: fromfrom odoo importimport Model,, api classclass stuff((Model):): @api.model@api.model defdef create((self,, values):): # self is a recordset, but its content is unused ...... This method definition is equivalent to: classclass stuff((Model):): defdef create((self,, cr,, uid,, values,, context==None):): # self is not a recordset ......
  • 12. Method decorators fromfrom odoo importimport Model,, api classclass stuff((Model):): @api.multi@api.multi defdef write((self,, values):): # self is a recordset and its content is used # update self.ids ...... This method definition is equivalent to: classclass stuff((Model):): defdef multi((self,, cr,, uid,, ids,, values,, context==None):): # self is not a recordset ......
  • 13. Method decorators One-by-one or "autoloop" decorator: fromfrom odoo importimport Model,, api classclass stuff((Model):): @api.one@api.one defdef cancel((self):): self..state == 'cancel' When invoked, the method is applied on every record: recs..cancel()() # [rec.cancel() for rec in recs]
  • 14. Method decorators Methods that return a recordset instead of ids: fromfrom odoo importimport Model,, api classclass stuff((Model):): @api.multi@api.multi @api.returns@api.returns(('res.partner')) defdef root_partner((self):): p == self..partner_id whilewhile p..parent_id:: p == p..parent_id returnreturn p When called with the old API, it returns ids: roots == recs..root_partner()() root_ids == model..root_partner((cr,, uid,, ids,, context==None))
  • 16. The environment object Encapsulates cr, uid, context: # recs.env encapsulates cr, uid, context recs..env..cr # shortcut: recs._cr recs..env..uid # shortcut: recs._uid recs..env..context # shortcut: recs._context # recs.env also provides helpers recs..env..user # uid as a record recs..env..ref(('base.group_user')) # resolve xml id recs..env[['res.partner']] # access to new-API model
  • 17. The environment object Switching environments: # rebrowse recs with different parameters env2 == recs..env((cr2,, uid2,, context2)) recs2 == recs..with_env((env2)) # special case: change/extend the context recs2 == recs..with_context((context2)) recs2 == recs..with_context((lang=='fr')) # kwargs extend current context # special case: change the uid recs2 == recs..sudo((user)) recs2 == recs..sudo()() # uid = SUPERUSER_ID
  • 19. Fields as descriptors Python descriptors provide getter/setter (like property): fromfrom odoo importimport Model,, fields classclass res_partner((Model):): _name == 'res.partner' name == fields..Char((required==True)) parent_id == fields..Many2one(('res.partner',, string=='Parent'))
  • 20. Computed fields Regular fields with the name of the compute method: classclass res_partner((Model):): ...... display_name == fields..Char(( string=='Name',, compute=='_compute_display_name',, )) @api.one@api.one @api.depends@api.depends(('name',, 'parent_id.name')) defdef _compute_display_name((self):): names == [[self..parent_id..name,, self..name]] self..display_name == ' / '..join((filter((None,, names))))
  • 21. Computed fields The compute method must assign field(s) on records: untaxed == fields..Float((compute=='_amounts')) taxes == fields..Float((compute=='_amounts')) total == fields..Float((compute=='_amounts')) @api.multi@api.multi @api.depends@api.depends(('lines.amount',, 'lines.taxes')) defdef _amounts((self):): forfor order inin self:: order..untaxed == sum((line..amount forfor line inin order..lines)) order..taxes == sum((line..taxes forfor line inin order..lines)) order..total == order..untaxed ++ order..taxes
  • 22. Computed fields Stored computed fields are much easier now: display_name == fields..Char(( string=='Name',, compute=='_compute_display_name',, store==True,, )) @api.one@api.one @api.depends@api.depends(('name',, 'parent_id.name')) defdef _compute_display_name((self):): ...... Field dependencies (@depends) are used for cache invalidation, recomputation, onchange. · · ·
  • 23. Fields with inverse On may also provide inverseinverse and searchsearch methods: classclass stuff((Model):): name == fields..Char()() loud == fields..Char(( store==False,, compute=='_compute_loud',, inverse=='_inverse_loud',, search=='_search_loud',, )) @api.one@api.one @api.depends@api.depends(('name')) defdef _compute_loud((self):): self..loud == ((self..name oror ''))..upper()() ......
  • 24. Fields with inverse classclass stuff((Model):): name == fields..Char()() loud == fields..Char(( store==False,, compute=='_compute_loud',, inverse=='_inverse_loud',, search=='_search_loud',, )) ...... @api.one@api.one defdef _inverse_loud((self):): self..name == ((self..loud oror ''))..lower()() defdef _search_loud((self,, operator,, value):): ifif value isis notnot False:: value == value..lower()() returnreturn [([('name',, operator,, value)])]
  • 25. Onchange methods For computed fields: nothing to do!nothing to do! For other fields: API is similar to compute methods: @api.onchange@api.onchange(('partner_id')) defdef _onchange_partner((self):): ifif self..partner_id:: self..delivery_id == self..partner_id The record self is a virtual record: all form values are set on self assigned values are not written to database but returned to the client · ·
  • 26. Onchange methods A field element on a form is automaticallyautomatically decorated with on_change="1": if it has an onchange method if it is a dependency of a computed field This mechanism may be prevented by explicitly decorating a field element with on_change="0". · ·
  • 27. Python constraints Similar API, with a specific decorator: @api.one@api.one @api.constrains@api.constrains(('lines',, 'max_lines')) defdef _check_size((self):): ifif len((self..lines)) >> self..max_lines:: raiseraise WarningWarning((_(("Too many lines in %s")) %% self..name)) The error message is provided by the exception.
  • 29. Guidelines Do the migration step-by-step: 1. migrate field definitions rewrite compute methods 2. migrate methods rely on interoperability use decorators, they are necessary 3. rewrite onchange methods (incompatible API) beware of overridden methods! · · · ·
  • 30. From V7 to V8: The New API Thanks!