構(gòu)建Odoo模塊教程_第1頁
構(gòu)建Odoo模塊教程_第2頁
構(gòu)建Odoo模塊教程_第3頁
構(gòu)建Odoo模塊教程_第4頁
構(gòu)建Odoo模塊教程_第5頁
已閱讀5頁,還剩12頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

構(gòu)建Odoo模塊模塊組成o業(yè)務(wù)對象業(yè)務(wù)對象聲明為Python類,由Odoo自動載入o數(shù)據(jù)文件XML或CSV文件格式,在其中聲明了元數(shù)據(jù)(視圖或工作流)、配置數(shù)據(jù)(模塊參數(shù))、演示數(shù)據(jù)等.oWeb控制器處理Web瀏覽器發(fā)來的requests.o靜態(tài)web數(shù)據(jù)丄W^用到的圖像,CSS或JavaScript文件.模塊結(jié)構(gòu)一個Odoo模塊也是一個Python模塊,存放在一個目錄中,包含一個―init_.py文件,用于導(dǎo)入其他Python模塊.from?importmymoduleodoo.py提供了一個子命令scaffold可以方便地創(chuàng)建一個空的模塊.$odoo.pyscaffold<modulename><wheretoputit>命令執(zhí)行后,將會創(chuàng)建一個子目錄并且其中包括了Odoo模塊所需的一些基本文件.練習(xí)#1執(zhí)行./odoo.pyscaffoldopenacademyaddons,在addons目錄下創(chuàng)建一個名為openacademy的模塊,生成的目錄文件結(jié)構(gòu)如下.openacademy|——security各文件內(nèi)容請查看文件或查看原文,然后對_openerp_.py中的幾種標(biāo)識文本進(jìn)行修改,至少需要添加'installable':True,'application':True。對象關(guān)系映射ORM層是Odoo的一個關(guān)鍵組件,它可以防止大部分的SQL語句編寫從而提高擴(kuò)展性和安全性.業(yè)務(wù)對象用派生自Model的Python類(模型)來編寫,該類的_name屬性定義了模型在Odoo系統(tǒng)中的名稱.fromopenerpimportmodelsclassMinimalModel(models.Model):^字段ame='test.model'字段定義模型能夠存儲什么以及在哪里存儲,字段在模型類中用屬性來定義.fromopenerpimportmodels,fieldsclassLessMinimalModel(models.Model):_name='test?model2'通用屬性fieldsChar()與模型類似,字段也可以通過參數(shù)傳遞對其進(jìn)行設(shè)定:name=field?Char(required二True)字段的常用屬性有:ostring(unicode,default:field'sname)字段標(biāo)簽名稱,會顯示在界面上〔對用戶可見〕。orequired(bool,default:False)如果值為True,此字段值不能為空,設(shè)置默認(rèn)值或者在創(chuàng)建記錄時提供。ohelp(unicode,default:")界面上顯示提示語。oindex(bool,default:False)如果值為True,創(chuàng)建表時將為此列添加索引。簡單字段字段可以分為兩類:簡單字段和關(guān)系字段.前者為原子值,直接保存在模型對應(yīng)的數(shù)據(jù)庫表中;后者連接到其他的記錄上(可以是相同的模型也可以是不同的模型).Boolean,Date,Char這些都是簡單字段.保留字段Odoo在模型中自動創(chuàng)建并維護(hù)一些字段,這些字段就是保留字段,這些字段數(shù)據(jù)不需要也不應(yīng)該手動去修改.oid(Id)

—條記錄的唯一id。ocreate_date(Datetime)記錄創(chuàng)建時間。ocreate_uid(Many2one)誰創(chuàng)建的記錄。owrite_date(Datetime)最后修改時間。owrite_uid(Many2one)誰最后修改的記錄。特殊字段默認(rèn)情況下,Odoo要求模型中有一個name字段,用于顯示和搜索,通過設(shè)置_rec_name也可以到達(dá)這樣的目的.練習(xí)#2在openacademy模塊中定義一個新的模型Courseopenacademy/models.py內(nèi)容如下:#-*-coding:utf-8-*-fromopenerpimportmodels,fields,apiclassCourse(models.Model):_name='openacademy.course'name=fields?Char(string"Title",required二True)數(shù)據(jù)文件ion=fields?Text()Odoo是一個高度數(shù)據(jù)驅(qū)動的系統(tǒng),雖然使用Python代碼來定制模塊行為,但很多模塊數(shù)據(jù)是在其載入時setup的,并且有些模塊僅僅為Odoo添加數(shù)據(jù).通過數(shù)據(jù)文件來定義模塊數(shù)據(jù),例如可以使用XML文件中的<record>元素定義數(shù)據(jù),每一個<record>元素創(chuàng)建或者更新數(shù)據(jù)庫中的一條記錄,形式如下:<openerp><data><recordmodel二"{modelname}"id二"{recordidentifier}"><fieldname="{afieldname}">{avalue}</field></record></data><openerp>omodelOdoo模型名.oid夕卜部ID(ExternalIdentifier),通過它可以引用到記錄(并且不需要知道記錄所在的數(shù)據(jù)庫ID).o元素name屬性用于確定字段名稱(例如description),該元素的body給出字段的值.'data'列表(全部載入)或’demo'列表(只有設(shè)定為載入演示數(shù)據(jù)才會載入)中.練習(xí)#3'demo'列表中有該文件.<openerp><data><recordmodel="openacademy.course"id="course0"><fieldname="name">Course0</field><fieldname二"description">Course0'sdescriptionCanhavemultiplelines</field></record><recordmodel="openacademy.course"id="course1"><fieldname="name">Course1</field><!--nodescriptionforthisone--></record><recordmodel="openacademy.course"id="course2"><fieldname="name">Course2</field><fieldname="description">Course2'sdescription</field></record></data>動作和菜單在Odoo中,動作和菜單都是定義在數(shù)據(jù)庫中的數(shù)據(jù)記錄,一般通過數(shù)據(jù)文件來定義.動作可以由三種方式觸發(fā):o點(diǎn)擊菜單項(菜單項鏈接到特定動作)o點(diǎn)擊視圖上的按鈕(如果按鈕連接到動作)o作為對象的上下文動作

使用<menuitem>聲明一個ir.ui.menu并將其連接到一個action,可以用下面的形式的代碼.<recordmodel二"ir.actions.act_window"id="action_list_ideas"><fieldname="name">Ideas</field>fieldname="res_model">idea?idea</field>fieldname="view_mode">tree,form</field></record><menuitemid二"menu_ideas"parent二"menu_root"name二"Ideas"sequenee二"10"action二"aetion_list_ideas"/>注意:action必須先于menu的連接使用定義,數(shù)據(jù)文件在載入時順序地執(zhí)行,所以動作的ID必須首先存在于數(shù)據(jù)庫中才能使用.練習(xí)#4定義一個新的菜單項訪問OpenAcademy課程.創(chuàng)建openacademy/views/openacademy.xml文件,并在其中添加動作和菜單.<?xmlversion="1.0"encoding二"UTF-8"?><openerp><data><!--windowaction--><!--Thefollowingtagisanactiondefinitionfora"windowaction",thatisanactionopeningavieworasetofviews--><recordmodel二"ir.actions.act_window"id="course_list_action"><fieldname="name">Courses</field><fieldname="res_model"></field><fieldname="view_type">form</field><fieldname="view_mode">tree,form</field><fieldname二"help"type二"html"><pclass二"oe_view_nocontent_create">Createthefirstcourse</p></field></record><!--toplevelmenu:noparent--><menuitemid="main_openacademy_menu"name="OpenAcademy"/〉<!--Afirstlevelintheleftsidemenuisneededbeforeusingaction二attribute--><menuitemid="openacademy_menu"name="OpenAcademy"parenfmain_openacademy_menu"/><!--thefollowingmenuitemshouldappear*after*itsparentopenacademy_menuand*after*itsactioncourse_list_action--><menuitemid="courses_menu"name="Courses"parent二"openacademy_menuactio"course_list_action"/><!--Fullidlocation:action二"openacademy.course_list_action"Itisnotrequiredwhenitisthesamemodule--></data></openerp>'data'.'data':[#'security/ir.model.access.csv','templates.xml',以看到菜單,操作看看效果.'views/openacademy.xml',以看到菜單,操作看看效果.據(jù)如何顯示,每種類型的視圖代表一種數(shù)據(jù)可視化模式.—個視圖是以一條ir.ui.view模型數(shù)據(jù)的形式定義的.<recordmodel="ir?ui?view"id="view_id"><fieldname="name"></field><fieldname="model">object_name</field><fieldname="priority"eval="16"/><fieldname="arch"type="xml"><!--viewcontent:<form>,<tree>,<graph>,???--></field>

TreeviewsTreeview也被稱為listviews,在一個表格中顯示記錄.根元素是<tree>,最簡形式的treeview只是簡單地列出每條記錄的多個字段,每個字段為一列.<treestring="Idealist"〉<fieldname="name"/〉<fieldname="inventor_id"/>i^ormiviewsForm用于創(chuàng)建或編輯單條記錄,根元素是<form〉,可以在form中組合各種高層結(jié)構(gòu)元素(如groups,notebooks)以及交互元素(如buttons,fields).<formstring="Ideaform"〉<groupcolspan="4"><groupcolspan="2"col="2">〈separatorstring="Generalstuff"colspan="2"/><fieldname="name"/><fieldname="inventor_id"/></group><groupcolspan="2"col="2">〈separatorstring="Dates"colspan="2"/>fieldname="active"/>〈fieldname二"invent_date"readonly二"1"/></group><notebookcolspan="4"><pagestring="Description">〈fieldname二"description"nolabel="1"/></page></notebook>〈fieldname="state"/></group>練習(xí)>#5為openacademy創(chuàng)建formview,views/openacademy.xml數(shù)據(jù)文件中增加<recordmodel=””...>內(nèi)容.〈?xmlversion="1.0"encoding二"UTF-8"?><openerp><data><recordmodel="ir?ui?view"id="course_form_view"><fieldname="name">〈/field><fieldname="model"x/field><fieldname二"arch"type="xml"><formstring="CourseForm"><sheet>〈group><fieldname="name"/><fieldname="description"/>〈/group></sheet></form></field></record>〈!--windowaction--><!--Thefollowingtagisanactiondefinitionfora"windowaction",更新模塊,創(chuàng)建一個Course,可以看到formview變了.練習(xí)#6使用notebook在formview中,將description字段放在一個tab中,方便隨后添加其他tabs,對練習(xí)#5的formview數(shù)據(jù)做如下修改.<sheet>〈group><fieldname="name"/>〈/group>〈notebook><pagestring="Description"><fieldname="description"/></page>

<pagestring="About">Thisisanexampleofnotebooks</page></notebook></sheet></form></field>更新模塊,看效果.More還可以使用HTML為formview提供更加靈活的布局,例如下面的例子.<formstring="IdeaForm"〉<header><buttonstring="Confirm"type二"object"name="action_confirm"states二"draft"class二"oe_highlight"/><buttonstring="Markasdone"type二"object"name="action_done"states二"confirmed"class二"oe_highlight"/><buttonstring="Resettodraft"type="object"name="action_draft"states="confirmed,done"/>fieldname二"state"widget二"statusbar"/></header><sheet><divclass="oe_title"><labelfor="name"class二"oe_edit_only"string二"IdeaName"/><h1><fieldname="name"/></h1></div><separatorstring="General"colspan="2"/><groupcolspan="2"col="2"><fieldname二"description"placeholder二"Ideadescription..."/></group></sheet>searc±viewsSearchviews用來自定義listviews及其它統(tǒng)計/多條記錄視圖中的搜索字段.根元素為<search〉,其子元素定義了在哪些字段上進(jìn)行搜索.<search><fieldname="name"/〉<fieldname="inventor_id"/></search>如果一個模型沒有定義對應(yīng)的Searchview,odoo自動創(chuàng)建一個僅搜索name字段的searchview.練習(xí)#7添加title以及description搜索,在views/openacademy.xml中定義searchview.</field></record><recordmodel="ir?ui?view"id="course_search_view"><fieldname="name"></field><fieldname="model"></field><fieldname="arch"type二"xml"><search><fieldname="name"/〉<fieldname="description"/></search></field></record><!--windowaction--><!--isanactiondefinitionfora"windowaction",字符后可以看到下方能夠選擇搜索description字段.概述—個模型中的記錄可能關(guān)聯(lián)到其他模型的記錄,例如銷售訂單記錄會關(guān)聯(lián)到一個包含客戶信息的客戶記錄.練習(xí)#8為了說明數(shù)據(jù)關(guān)聯(lián),首先增加新的模型.OpenAcademy模塊中,一個session是一個在特定時間針對特定聽眾講授課程的過程.需要為session創(chuàng)建相應(yīng)的模型.session具有name,開始日期,持續(xù)時間以及座位數(shù)量等.此外還需要添加相應(yīng)的action和menuitem顯示模型數(shù)據(jù).

首先在openacademy/models.py中創(chuàng)建Session類.classSession(models.Model):_name='openacademy.session'name=fieldsChar(required二True)start_date=fieldsDate()duration二fieldsFloat(digits=(6,2),help二"Durationindays")seats=fieldsInteger(string="Numberofseats")然后在openacademy/view/openacademy.xml中添加用于訪問session模型的action和menuitem定義.<!--Fullidlocation:action二"openacademy.course_list_action"Itisnotrequiredwhenitisthesamemodule--><!--sessionformview--><recordmodel="ir?ui?view"id="session_form_view"><fieldname="name"></field><fieldname="model"></field><fieldname二"arch"type二"xml"><formstring="SessionForm"〉<sheet><group><fieldname="name"/〉<fieldname="start_date"/><fieldname="duration"/><fieldname="seats"/></group></sheet></form></field></record><recordmodel="ir.actions.act_window"id="session_list_action"><fieldname="name">Sessions</field><fieldname="res_model"></field><fieldname="view_type">form</field><fieldname="view_mode">tree,form</field></record><menuitemid="session_menu"name="Sessions"parenfopenacademy_menu"actiortsession_list_action"/></data></openerp>digits=(6,2)確定浮點(diǎn)數(shù)的精度,6表示總的數(shù)字位數(shù)(不包括小數(shù)點(diǎn)),2表示小數(shù)點(diǎn)后的位數(shù).所以,關(guān)聯(lián)字段」'數(shù)點(diǎn)前最多4位.關(guān)聯(lián)字段指向某些記錄,或者是相同的model(模型),或者是不同的model(模型)。關(guān)聯(lián)字段類型:Many2one(other_model,ondelete?'setnull')One2many(other_model,related_field)Many2many(other_model)練習(xí)#9概述使用many2one修改Course和Session模型(model),反映出與其他模型(model)的關(guān)聯(lián):每個Course有一"負(fù)責(zé)人,other_model值為每個Session有一"老師,other_model值為一"個Session關(guān)聯(lián)一"個Course,other_model值為,必填調(diào)整view。添加相關(guān)字段Many2One到model添加到viewname=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="lnstructor")course_id=fields.Many2one('openacademy.course',ondelete='cascade',string="Course",required=True)<sheet><group><fieldname="name"/><fieldname="responsible_id"/></group><notebook><pagestring="Description"></field></record><!--overridetheautomaticallygeneratedlistviewforcourses--><recordmodel="ir.ui.view"id="course_tree_view"><fieldname="name">course.tree</field><fieldname="model">openacademy.course</field><fieldname="arch"type="xml"><treestring="CourseTree"><fieldname="name"/><fieldname="responsible_id"/></tree></field></record><!--windowaction--><!--Thefollowingtagisanactiondefinitionfora"windowaction",<formstring="SessionForm"><sheet><group><groupstring="General"><fieldname="course_id"/><fieldname="name"/><fieldname="instructor_id"/></group><groupstring="Schedule"><fieldname="start_date"/><fieldname="duration"/><fieldname="seats"/></group></group></sheet></form></field></record><!--sessiontree/listview--><recordmodel="ir.ui.view"id="session_tree_view"><fieldname="name">session.tree</field><fieldname="model">openacademy.session</field><fieldname="arch"type="xml"><treestring="SessionTree"><fieldname="name"/><fieldname="course_id"/></tree></field></record>vrecordmodel="ir.actions.act_window"id="session」ist_action"><fieldname="name">Sessions</field>vfieldname="res_model"x/field>ExerciseInverseone2manyrelationsUsingtheinverserelationalfieldone2many,modifythemodelstoreflecttherelationbetweencoursesandsessions.ModifytheCourseclass,andaddthefieldinthecourseformview.responsible_id=fields.Many2one('res.users',ondelete='setnull',string="Responsible",index=True)session_ids=fields.One2many('openacademy.session','course_id',string="Sessions")classSession(models.Model):<pagestring="Description"><fieldname="description"/></page><pagestring="Sessions"><fieldname="session_ids"><treestring="Registeredsessions"><fieldname="name"/><fieldname="instructor_id"/></tree></field></page></notebook></sheet>ExerciseMultiplemany2manyrelationsUsingtherelationalfieldmany2many,modifytheSessionmodeltorelateeverysessiontoasetofattendees.Attendeeswillberepresentedbypartnerrecords,sowewillrelatetothebuilt-inmodel.Adapttheviewsaccordingly.ModifytheSessionclass,andaddthefieldintheformview.instructor_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")<fieldname="seats"/></group></group><labelfor="attendee_ids"/><fieldname="attendee_ids"/></sheet></form>InheritanceModelinheritanceOdooprovidestwoinheritancemechanismstoextendanexistingmodelinamodularway.Thefirstinheritancemechanismallowsamoduletomodifythebehaviorofamodeldefinedinanothermodule:addfieldstoamodel,overridethedefinitionoffieldsonamodel,addconstraintstoamodel,addmethodstoamodel,overrideexistingmethodsonamodel.Thesecondinheritancemechanism(delegation)allowstolink?veryrecordofamodeltoarecordinaparentmodel,andprovidestransparentaccesstothefieldsoftheparentrecord.-Seealso_inherit—inherits

ViewinheritanceInsteadofmodifyingexistingviewsinplace(byoverwritingthem),Odooprovidesviewinheritancewherechildren"extension"viewsareappliedontopofrootviews,andcanaddorremovecontentfromtheirparent.Anextensionviewreferencesitsparentusingtheinherit_idfield,andinsteadofasingleviewitsarchfieldiscomposedofanynumberofxpathelementsselectingandalteringthecontentoftheirparentview:<!--improvedideacategorieslist--><recordid="idea_category_list2"model="ir.ui.view"><fieldname="name">v/field><fieldname="model"></field><fieldname="inherit_id"ref="id_category_list"/><fieldname="arch"type="xml"><!--findfielddescriptionandaddthefieldidea_idsafterit--><xpathexpr="http://field[@name='description']"posit

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。