为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > Ooo模块开发全流程

Ooo模块开发全流程

2023-03-15 7页 pdf 3MB 2阅读

用户头像 个人认证

is_401170

暂无简介

举报
Ooo模块开发全流程构建Odoo模块模块组成o业务对象业务对象声明为Python类,由Odoo自动载入.o数据文件XML或CSV文件格式,在其中声明了元数据(视图或工作流)、配置数据(模块参数)、演示数据等.oWeb控制器处理Web浏览器发来的requests.o静态web数据Web用到的图像,CSS或JavaScript文件.模块结构一个Odoo模块也是一个Python模块,存放在一个目录中,包含一个__init__.py文件,用于导入其他Python模块.from.importmymoduleodoo.py提供了一个子命令scaffold可以...
Ooo模块开发全流程
构建Odoo模块模块组成o业务对象业务对象声明为Python类,由Odoo自动载入.o数据文件XML或CSV文件格式,在其中声明了元数据(视图或工作流)、配置数据(模块参数)、演示数据等.oWeb控制器处理Web浏览器发来的requests.o静态web数据Web用到的图像,CSS或JavaScript文件.模块结构一个Odoo模块也是一个Python模块,存放在一个目录中,包含一个__init__.py文件,用于导入其他Python模块.from.importmymoduleodoo.py提供了一个子命令scaffold可以方便地创建一个空的模块.$odoo.pyscaffold命令执行后,将会创建一个子目录并且其中包括了Odoo模块所需的一些基本文件.练习#1执行./odoo.pyscaffoldopenacademyaddons,在addons目录下创建一个名为openacademy的模块,生成的目录文件结构如下.openacademy├──__init__.py├──__openerp__.py├──controllers.py├──demo.xml├──models.py├──security└──templates.xml各文件内容请查看文件或查看原文,然后对__openerp__.py中的几种标识文本进行修改,至少需要添加'installable':True,'application':True。对象关系映射ORM层是Odoo的一个关键组件,它可以避免大部分的SQL语句编写从而提高扩展性和安全性.业务对象用派生自Model的Python类(模型)来编写,该类的_name属性定义了模型在Odoo系统中的名称.fromopenerpimportmodelsclassMinimalModel(models.Model):_name='test.model'字段字段定义模型能够存储什么以及在哪里存储,字段在模型类中用属性来定义.fromopenerpimportmodels,fieldsclassLessMinimalModel(models.Model):_name='test.model2'name=fields.Char()通用属性与模型类似,字段也可以通过参数传递对其进行设定:name=field.Char(required=True)字段的常用属性有:ostring(unicode,default:field’sname)字段标签名称,会显示在界面上(对用户可见)。orequired(bool,default:False)如果值为True,此字段值不能为空,设置默认值或者在创建记录时提供。ohelp(unicode,default:‘’)界面上显示语。oindex(bool,default:False)如果值为True,创建表时将为此列添加索引。简单字段字段可以分为两类:简单字段和关系字段.前者为原子值,直接保存在模型对应的数据库表中;后者连接到其他的记录上(可以是相同的模型也可以是不同的模型).Boolean,Date,Char这些都是简单字段.保留字段Odoo在模型中自动创建并维护一些字段,这些字段就是保留字段,这些字段数据不需要也不应该手动去修改.oid(Id)一条记录的唯一id。ocreate_date(Datetime)记录创建时间。ocreate_uid(Many2one)谁创建的记录。owrite_date(Datetime)最后修改时间。owrite_uid(Many2one)谁最后修改的记录。特殊字段默认情况下,Odoo要求模型中有一个name字段,用于显示和搜索,通过设置_rec_name也可以达到这样的目的.练习#2在openacademy模块中定义一个新的模型Course,openacademy/models.py内容如下:#-*-coding:utf-8-*-fromopenerpimportmodels,fields,apiclassCourse(models.Model):_name='openacademy.course'name=fields.Char(string="Title",required=True)description=fields.Text()数据文件Odoo是一个高度数据驱动的系统,虽然使用Python代码来定制模块行为,但很多模块数据是在其载入时setup的,并且有些模块仅仅为Odoo添加数据.通过数据文件来定义模块数据,例如可以使用XML文件中的元素定义数据,每一个元素创建或者更新数据库中的一条记录,形式如下:{avalue}omodelOdoo模型名.oid外部ID(ExternalIdentifier),通过它可以引用到记录(并且不需要知道记录所在的数据库ID).o元素name属性用于确定字段名称(例如description),该元素的body给出字段的值.数据文件必须在模块载入文件列表中,也就是__openerp__.py的’data’列表(全部载入)或’demo’列表(只有设定为载入演示数据才会载入)中.练习#3创建一个数据文件来向Course中添加数据,编辑openacademy/demo.xml,并确认__openerp__.py的’demo’列表中有该文件.Course0Course0'sdescriptionCanhavemultiplelinesCourse1Course2Course2'sdescription动作和菜单在Odoo中,动作和菜单都是定义在数据库中的数据记录,一般通过数据文件来定义.动作可以由三种方式触发:o点击菜单项(菜单项链接到特定动作)o点击视图上的按钮(如果按钮连接到动作)o作为对象的上下文动作Ideasidea.ideatree,form注意:action必须先于menu的连接使用定义,数据文件在载入时顺序地执行,所以动作的ID必须首先存在于数据库中才能使用.练习#4定义一个新的菜单项访问OpenAcademy课程.创建openacademy/views/openacademy.xml文件,并在其中添加动作和菜单.Coursesopenacademy.courseformtree,formCreatethefirstcourse

在__openerp__.py中添加这个数据文件名到’data’.'data':['templates.xml','views/openacademy.xml',],更新模块后可以看到菜单,操作看看效果.基本视图视图定义了模型数据如何显示,每种类型的视图代表一种数据可视化模式.基本的视图定义view.nameobject_nameTreeviewsTreeview也被称为listviews,在一个表格中显示记录.根元素是,最简形式的treeview只是简单地列出每条记录的多个字段,每个字段为一列.FormviewsForm用于创建或编辑单条记录,根元素是
,可以在form中组合各种高层结构元素(如groups,notebooks)以及交互元素(如buttons,fields).练习#5为openacademy创建formview,views/openacademy.xml数据文件中增加内容.course.formopenacademy.coursesession.formopenacademy.sessionSessionsopenacademy.sessionformtree,formdigits=(6,2)确定浮点数的精度,6表示总的数字位数(不包括小数点),2表示小数点后的位数.所以,digits=(6,2)小数点前最多4位.关联字段关联字段指向某些记录,或者是相同的model(模型),或者是不同的model(模型)。关联字段类型:练习#9概述•使用修改和模型,反映出与其他模型的关联:•每个有一个负责人,值为res.users•每个有一个老师,值为res.partner•一个关联一个,值为openacademy.course,必填•调整。添加相关字段到添加到name=fields.Char(string="Title",required=True)description=fields.Text()responsible_id=fields.Many2one('res.users',ondelete='setnull',string="Responsible",index=True)classSession(models.Model):_name='openacademy.session'start_date=fields.Date()duration=fields.Float(digits=(6,2),help="Durationindays")seats=fields.Integer(string="Numberofseats")instructor_id=fields.Many2one('res.partner',string="Instructor")course_id=fields.Many2one('openacademy.course',ondelete='cascade',string="Course",required=True)course.treeopenacademy.coursesession.treeopenacademy.sessionSessionsopenacademy.sessionExerciseInverseone2manyrelationsUsingtheinverserelationalfieldone2many,modifythemodelstoreflecttherelationbetweencoursesandsessions.1.Modifythe?Course?class,and2.addthefieldinthecourseformview.openacademy/models.pyresponsible_id=fields.Many2one('res.users',ondelete='setnull',string="Responsible",index=True)session_ids=fields.One2many('openacademy.session','course_id',string="Sessions")classSession(models.Model):openacademy/views/openacademy.xmlExerciseMultiplemany2manyrelationsUsingtherelationalfieldmany2many,modifythe?Session?modeltorelateeverysessiontoasetof?attendees.Attendeeswillberepresentedbypartnerrecords,sowewillrelatetothebuilt-inmodel?res.partner.Adapttheviewsaccordingly.1.Modifythe?Session?class,and2.addthefieldintheformview.openacademy/models.pyinstructor_id=fields.Many2one('res.partner',string="Instructor")course_id=fields.Many2one('openacademy.course',ondelete='cascade',string="Course",required=True)attendee_ids=fields.Many2many('res.partner',string="Attendees")openacademy/views/openacademy.xmlInheritanceModelinheritanceOdooprovidestwo?inheritance?mechanismstoextendanexistingmodelinamodularway.Thefirstinheritancemechanismallowsamoduletomodifythebehaviorofamodeldefinedinanothermodule:•addfieldstoamodel,•overridethedefinitionoffieldsonamodel,•addconstraintstoamodel,•addmethodstoamodel,•overrideexistingmethodsonamodel.Thesecondinheritancemechanism(delegation)allowstolinkeveryrecordofamodeltoarecordinaparentmodel,andprovidestransparentaccesstothefieldsoftheparentrecord.Seealso•_inherit•_inheritsViewinheritanceInsteadofmodifyingexistingviewsinplace(byoverwritingthem),Odooprovidesviewinheritancewherechildren"extension"viewsareappliedontopofrootviews,andcanaddorremovecontentfromtheirparent.Anextensionviewreferencesitsparentusingthe?inherit_id?field,andinsteadofasingleviewits?arch?fieldiscomposedofanynumberof?xpath?elementsselectingandalteringthecontentoftheirparentview:idea.categoryexprAn?XPath?expressionselectingasingleelementintheparentview.RaisesanerrorifitmatchesnoelementormorethanonepositionOperationtoapplytothematchedelement:insideappends?xpath'sbodyattheendofthematchedelementreplacereplacesthematchedelementbythe?xpath'sbodybeforeinsertsthe?xpath'sbodyasasiblingbeforethematchedelementafterinsertsthe?xpaths'sbodyasasiblingafterthematchedelementattributesalterstheattributesofthematchedelementusingspecial?attribute?elementsinthe?xpath'sbodyTipWhenmatchingasingleelement,the?position?attributecanbesetdirectlyontheelementtobefound.Bothinheritancesbelowwillgivethesameresult.ExerciseAlterexistingcontent•Usingmodelinheritance,modifytheexisting?Partner?modeltoaddan?instructor?booleanfield,andamany2manyfieldthatcorrespondstothesession-partnerrelation•Usingviewinheritance,displaythisfieldsinthepartnerformviewNoteThisistheopportunitytointroducethedevelopermodetoinspecttheview,finditsexternalIDandtheplacetoputthenewfield.1.Createafile?openacademy/partner.py?andimportitin?__init__.py2.Createafile?openacademy/views/partner.xml?andadditto?__openerp__.pyopenacademy/__init__.py#-*-coding:utf-8-*-from.importcontrollersfrom.importmodelsfrom.importpartneropenacademy/__openerp__.py'templates.xml','views/openacademy.xml','views/partner.xml',],#onlyloadedindemonstrationmode'demo':[openacademy/partner.py#-*-coding:utf-8-*-fromopenerpimportfields,modelsclassPartner(models.Model):_inherit='res.partner'#Addanewcolumntotheres.partnermodel,bydefaultpartnersarenot#instructorsinstructor=fields.Boolean("Instructor",default=False)session_ids=fields.Many2many('openacademy.session',string="AttendedSessions",readonly=True)openacademy/views/partner.xmlpartner.instructorres.partnerContactsres.partnertree,formDomainsInOdoo,?Domains?arevaluesthatencodeconditionsonrecords.Adomainisalistofcriteriausedtoselectasubsetofamodel'srecords.Eachcriteriaisatriplewithafieldname,anoperatorandavalue.Forinstance,whenusedonthe?Product?modelthefollowingdomainselectsall?services?withaunitpriceover?1000:[('product_type','=','service'),('unit_price','>',1000)]BydefaultcriteriaarecombinedwithanimplicitAND.Thelogicaloperators?&?(AND),?|?(OR)and?!?(NOT)canbeusedtoexplicitlycombinecriteria.Theyareusedinprefixposition(theoperatorisinsertedbeforeitsargumentsratherthanbetween).Forinstancetoselectproducts"whichareservices?OR?haveaunitpricewhichis?NOT?between1000and2000":['|',('product_type','=','service'),'!','&',('unit_price','>=',1000),('unit_price','<',2000)]A?domain?parametercanbeaddedtorelationalfieldstolimitvalidrecordsfortherelationwhentryingtoselectrecordsintheclientinterface.ExerciseDomainsonrelationalfieldsWhenselectingtheinstructorfora?Session,onlyinstructors(partnerswith?instructor?setto?True)shouldbevisible.openacademy/models.pyduration=fields.Float(digits=(6,2),help="Durationindays")seats=fields.Integer(string="Numberofseats")instructor_id=fields.Many2one('res.partner',string="Instructor",domain=[('instructor','=',True)])course_id=fields.Many2one('openacademy.course',ondelete='cascade',string="Course",required=True)attendee_ids=fields.Many2many('res.partner',string="Attendees")NoteAdomaindeclaredasaliterallistisevaluatedserver-sideandcan'trefertodynamicvaluesontheright-handside,adomaindeclaredasastringisevaluatedclient-sideandallowsfieldnamesontheright-handsideExerciseMorecomplexdomainsCreatenewpartnercategories?Teacher/Level1?and?Teacher/Level2.Theinstructorforasessioncanbeeitheraninstructororateacher(ofanylevel).1.Modifythe?Session?model'sdomain2.Modify?openacademy/view/partner.xml?togetaccessto?Partnercategories:openacademy/models.pyseats=fields.Integer(string="Numberofseats")instructor_id=fields.Many2one('res.partner',string="Instructor",domain=['|',('instructor','=',True),('category_id.name','ilike',"Teacher")])course_id=fields.Many2one('openacademy.course',ondelete='cascade',string="Course",required=True)attendee_ids=fields.Many2many('res.partner',string="Attendees")openacademy/views/partner.xmlContactTagstree,formTeacher/Level1Teacher/Level2ComputedfieldsanddefaultvaluesSofarfieldshavebeenstoreddirectlyinandretrieveddirectlyfromthedatabase.Fieldscanalsobe?computed.Inthatcase,thefield'svalueisnotretrievedfromthedatabasebutcomputedon-the-flybycallingamethodofthemodel.Tocreateacomputedfield,createafieldandsetitsattribute?compute?tothenameofamethod.Thecomputationmethodshouldsimplysetthevalueofthefieldtocomputeoneveryrecordin?self.Dangerself?isacollectionTheobject?self?isa?recordset,i.e.,anorderedcollectionofrecords.ItsupportsthestandardPythonoperationsoncollections,like?len(self)?and?iter(self),plusextrasetoperationslike?recs1+recs2.Iteratingover?self?givestherecordsonebyone,whereeachrecordisitselfacollectionofsize1.Youcanaccess/assignfieldsonsinglerecordsbyusingthedotnotation,like?record.name.importrandomfromopenerpimportmodels,fields,apiclassComputedModel(models.Model):_name='test.computed'name=fields.Char(compute='_compute_name')@api.multidef_compute_name(self):forrecordinself:record.name=str(random.randint(1,1e6))DependenciesThevalueofacomputedfieldusuallydependsonthevaluesofotherfieldsonthecomputedrecord.TheORMexpectsthedevelopertospecifythosedependenciesonthecomputemethodwiththedecorator?depends().ThegivendependenciesareusedbytheORMtotriggertherecomputationofthefieldwheneversomeofitsdependenciesh
/
本文档为【Ooo模块开发全流程】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索