版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
o數(shù)據(jù)文件oWeb控制器處理Web瀏覽器發(fā)來(lái)的requests.webWeb用到的圖像,CSS或文件.模塊結(jié)構(gòu)OdooPython,包含一個(gè)文件,用于導(dǎo)入其他Python模塊.from.importmymodule提供了一個(gè)子命令scaffold可以方便地創(chuàng)建一個(gè)空的模塊.$scaffold<modulename><wheretoputit>命令執(zhí)行后,將會(huì)創(chuàng)建一個(gè)子目錄并且其中包括了Odoo模塊所需的一些基本文件.#1affoldopenacademyaddonsaddonsopenacademy的模塊,生成的目錄文件結(jié)構(gòu)如下.openacademycurity各文件內(nèi)容請(qǐng)查看文件或查看,然后對(duì)中的幾種標(biāo)識(shí)文本進(jìn)行修改,至少需要添加'installable':True,'application':True。對(duì)象關(guān)系映射ORMOdooSQL寫從而提高擴(kuò)展性和安全性.ModelPython來(lái)編寫,該類的_name屬性定義了模型在Odoo系統(tǒng)中的名稱.fromopenerpimportmodelsl__name=''fromopenerpimportmodels,fieldsclassLessMinimalModel:_name=''name=()與模型類似,字段也可以通過參數(shù)傳遞對(duì)其進(jìn)行設(shè)定:name=(required=True)ostring(unicode,default:field’sname)字段標(biāo)簽名稱,會(huì)顯示在界面上(對(duì)用戶可見)。orequired(bool,default:False)界面上顯示提示語(yǔ)。ltFalsee為原子值,直接保存在模型對(duì)應(yīng)的表中;后者連接到其他的記錄上(可以是相同的模型也可以是不同的模型).DateCharOdoo段,這些字段就是保留字段,這些字段數(shù)據(jù)不需要手動(dòng)去修改.docreate_date(Datetime)記錄創(chuàng)建時(shí)間。ocreate_uid(Many2one)誰(shuí)創(chuàng)建的記錄。owrite_date(Datetime)最后修改時(shí)間。owrite_uid(Many2one)誰(shuí)最后修改的記錄。_rec_name也可以達(dá)到這樣的目的.#2#-*-coding:utf-8-*-fromopenerpimportmodels,fields,api_name=''name=(string="Title",required=True)description=()數(shù)據(jù)文件Odoo使用Python代碼來(lái)定制模塊行為,但很多模塊在其載入時(shí)setup的,并且有些模塊僅僅為Odoo添加數(shù)據(jù).XML文件中的<record>元素定義數(shù)據(jù),每record形式如下:<openerp><data><recordmodel="{modelname}"id="{recordidentifier}"><fieldname="{afieldname}">{avalue}</field></record></data><openerp>Odoo模型名.oidIDExternalIdentifier且不需要知道記錄所在的數(shù)據(jù)庫(kù)ID).o素name確定字段名稱(例如description),該元素的body給出字段的值.數(shù)據(jù)文件必須在模塊載入清單文件列表中,也就是的’data’列表(全部載入)或’demo’列表(只有設(shè)定為載入演示數(shù)據(jù)才會(huì)載入)中.練習(xí)#t創(chuàng)建一個(gè)數(shù)據(jù)文件來(lái)向Course中添加數(shù)據(jù),編輯openacademy/,并確認(rèn)的’demo’列表中有該文件.<openerp><data><recordmodel=""id="course0"><fieldname="name">Course0</field><fieldname="description">Course0'sdescriptionCanhavemultiplelines</field></</record><recordmodel=""id="course1"><fieldname="name">Course1</field><!--nodescriptionforthisone--></record><recordmodel=""id="course2"><fieldname="name">Course2</field><fieldname="description">Course2'sdescription</field></record></data></openerp>動(dòng)作和菜單在Odoo中,動(dòng)作和菜單都是定義在數(shù)據(jù)庫(kù)中的數(shù)據(jù)記錄,一般通過數(shù)據(jù)文件來(lái)定義.o定動(dòng)作)o連接到動(dòng)作)o作為對(duì)象的上下文動(dòng)作<recordmodel=id="action_list_ideas"><fieldname="name">Ideas</field><fieldname="res_model"></field><fieldname="view_mode">tree,form</field></record><menuitemid="menu_ideas"parent="menu_root"name="Ideas"sequence="10"action="action_list_ideas"/>注意:action必須先于menu的連接使用定義,數(shù)據(jù)文件在載入時(shí)順序地執(zhí)行,所以動(dòng)作ID庫(kù)中才能使用.#4定義一個(gè)新的菜單項(xiàng)訪問OpenAcademy課程.創(chuàng)建openacademy/views/文件,并在其中添加動(dòng)作和菜單.<xmlversion=""encoding="UTF-8"><openerp><data><!--windowaction--><!--Thefollowingtagisanactiondefinitionfora"windowaction",thatisanactionopeningavieworasetofviews--><recordmodel=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"parent="main_openacademy_menu"/><!--thefollowingmenuitemshouldappear*after*itsparentopenacademy_menuand*after*itsactioncourse_list_action--><menuitemid="courses_menu"name="Courses"parent="openacademy_menu"action="course_list_action"/><!--Fullidlocation:action=""Itisnotrequiredwhenitisthesamemodule--></data></openerp>'data':[模塊后可以看到菜單,操作看看效果.視圖代表一種數(shù)據(jù)可視化模式.基本的視圖定義<recordmodel=id="view_id"><fieldname="name"></field><fieldname="model">object_name</field><fieldname="priority"eval="16"/><fieldname="arch"type="xml"><!--viewcontent:<form>,<tree>,<graph>,...--></field></record>TreeviewsTreeviewlistviews,在一個(gè)表格中顯示記錄.根元素是<tree>,最簡(jiǎn)形式的treeview只是簡(jiǎn)單地列出每條記錄的多個(gè)字段,每個(gè)字段為一列.<treestring="Idealist"><fieldname="name"/><fieldname="inventor_id"/></tree>Formviewsmformformgroupsnotebooksbuttons,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></form>練習(xí)#Sopenacademyformviewviewsrecordmodel…>內(nèi).<xmlversion=""encoding="UTF-8"><openerp><data><recordmodel=id="course_form_view"><fieldname="name"></field><fieldname="model"></field><fieldname="arch"type="xml"><formstring="CourseForm"><sheet><group><fieldname="name"/><fieldname="description"/></group></sheet></form></field></record><!--windowaction--><!--Thefollowingtagisanactiondefinitionfora"windowaction",模塊,創(chuàng)建一個(gè)Course,可以看到formview變了.#9b他tabs,對(duì)練習(xí)#5的formview數(shù)據(jù)做如下修改.<sheet><group><fieldname="name"/></group><notebook><pagestring="Description"><fieldname="description"/></page><pagestring="About">Thisisanexampleofnotebooks</page></notebook></sheet></form></field>塊,看效果.還可以使用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></form>SearchviewsSearchviewslistviews圖中的搜索字段.根元素為<search><fieldname="name"/><fieldname="inventor_id"/></search>Searchviewodoo動(dòng)創(chuàng)建一個(gè)僅搜索name字段的searchview.#7添加title以及description搜索,在views/中定義searchview.</field></record><recordmodel=id="course_search_view"><fieldname="name"></field><fieldname="model"></field><fieldname="arch"type="xml"><search><fieldname="name"/>classSession:<fieldname="description"/></search></field></record><!--windowaction--><!--Thefollowingtagisanactiondefinitionfora"windowaction",夠選擇搜索description字段.一個(gè)模型中的記錄可能關(guān)聯(lián)到其他模型的記錄,例如銷售訂單記錄會(huì)關(guān)聯(lián)到一個(gè)包含客息的客戶記錄.#8說明數(shù)據(jù)關(guān)聯(lián),首先增加新的模型.OpenAcademysession特定時(shí)間針對(duì)特定聽眾講授課程的過程.session創(chuàng)建相應(yīng)的模型.sessionname位數(shù)量等.此外還需要添加相應(yīng)的action和menuitem顯示模型數(shù)據(jù).首先在openacademy/中創(chuàng)建Session類._name=''name=(required=True)start_date=()duration=(digits=(6,2),help="Durationindays")seats=(string="Numberofseats")openacademyviewsession模型的action和menuitem定<!--Fullidlocation:action=""Itisnotrequiredwhenitisthesamemodule--><!--sessionformview--><recordmodel=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=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"parent="openacademy_menu"action="session_list_action"/></data></openerp>digits表示總的數(shù)字位數(shù)(不包括小數(shù)點(diǎn)),2表示小數(shù)點(diǎn)后的位數(shù).所以,digits=(6,2)小數(shù)點(diǎn)前最多4位.關(guān)聯(lián)字段#6?????負(fù)責(zé)人,。name=(string="Title",required=True)description=()responsible_id=('',ondelete='setnull',string="Responsible",index=True)_name=''start_date=()duration=(digits=(6,2),help="Durationindays")seats=(string="Numberofseats")instructor_id=('',string="Instructor")course_id=('',ondelete='cascade',string="Course",required=True)<sheet><group><fieldname="name"/><fieldname="responsible_id"/></group><notebook><pagestring="Description"></field></record><!--overridetheautomaticallygeneratedlistviewforcourses--><recordmodel=id="course_tree_view"><fieldname="name"></field><fieldname="model"></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=id="session_tree_view"><fieldname="name"></field><fieldname="model"></field><fieldname="arch"type="xml"><treestring="SessionTree"><fieldname="name"/><<fieldname="course_id"/></tree></field></record><recordmodel=id="session_list_action"><fieldname="name">Sessions</field><fieldname="res_model"></field>seInverseone2manyrelationsUsingtheinverserelationalfieldone2many,modifythemodelstoreflecttherelationbetweencoursesandsessions.11.ModifytheCourseclass,and2.addthefieldinthecourseformview.openacademyopenacademy/responsible_id=('',ondelete='setnull',string="Responsible",index=True)session_ids=('','course_id',string="Sessions")classSession:openacademy/views/<pagestring="Description"><fieldname="description"/><pagestring="Sessions"><fieldname="session_ids"><treestring="Registeredsessions"><fieldname="name"/><fieldname="instructor_id"/>seMultiplemany2manyrelationsUsingtherelationalfieldmany2many,modifytheSessionmodeltorelateeverysessiontoasetofattendees.Attendeeswillberepresentedbypartnerrecords,sowewillrelatetothebuilt-inmodel.Adapttheviewsaccordingly.1.1.ModifytheSessionclass,and2.addthefieldintheformview.openacademyopenacademy/instructor_id=('',string="Instructor")course_id=('',ondelete='cascade',string="Course",required=True)attendee_ids=('',string="Attendees")openacademy/views/<fieldname="seats"/><labelfor="attendee_ids"/><fieldname="attendee_ids"/>??Odooprovidestwoinheritancemechanismstoextendanexistingmodelinamodularway.Thefirstinheritancemechanismallowsamoduletomodifythebehaviorofamodeldefinedinanothermodule:?????addfieldstoamodel,overridethedefinitionoffieldsonamodel,addconstraintstoamodel,addmethodstoamodel,overrideexistingmethodsonamodel.Thesecondinheritancemechanism(delegation)allowstolinkeveryrecordofamodeltoarecordinaparentmodel,andprovidestransparentaccesstothefieldsoftheparentrecord.Seealso??Insteadofmodifyingexistingviewsinplace(byoverwritingthem),Odooprovidesviewinheritancewherechildren"extension"viewsareappliedontopofrootviews,andcanaddorremovecontentfromtheirparent.AnAnextensionviewreferencesitsparentusingtheinherit_idfield,andinsteadofasingleviewitsarchfieldiscomposedofanynumberofxpathelementsselectingandalteringthecontentoftheirparentview:<!--improvedideacategorieslist--><recordid="idea_category_list2"model=><fieldname="name"></field><fieldname="model"></field><fieldname="inherit_id"ref="id_category_list"/><fieldname="arch"type="xml"><!--findfielddescriptionandaddthefieldidea_idsafterit--><xpathexpr="RaisesanerrorifitmatchesnoelementormorethantionOperationtoapplytothematchedelement:appendsxpath'sbodyattheendofthematchedelementreplacesreplacesthematchedelementbythexpath'sbodyinsertsinsertsthexpath'sbodyasasiblingbeforethematchedelementinsertsinsertsthexpaths'sbodyasasiblingafterthematchedelementattrattributesaltersalterstheattributesofthematchedelementusingspecialattributeelementsininthexpath'sbodyTipWhenWhenmatchingasingleelement,thepositionattributecanbesetdirectlyontheelementtobefound.Bothinheritancesbelowwillgivethesameresult.1.<xpathexpr="Createafileopenacademy/andimportitin2.Createafileopenacademy/views/andaddittoopenacademyopenacademy/#-*-coding:utf-8-*-from.importcontrollersfrom.importmodelsfrom.importpartneropenacademy/'','views/','views/',#onlyloadedindemonstrationmode'demo':[openacademy/#-*-coding:utf-8-*-fromopenerpimportfields,modelsclassPartner:_inherit=''#Addanewcolumntothemodel,bydefaultpartnersarenot#instructorsinstructor=("Instructor",default=False)session_ids=('',string="AttendedSessions",readonly=True)openacademy/views/<xmlversion=""encoding="UTF-8">rp<!--Addinstructorfieldtoexistingview--><recordmodel=id="partner_instructor_form_view"><fieldname="name"></field><fieldname="model"></field><fieldname="inherit_id"ref=""/><fieldname="arch"type="xml"><notebookposition="inside"><pagestring="Sessions"><fieldname="instructor"/><fieldname="session_ids"/>rd<recordmodel=id="contact_list_action"><fieldname="name">Contacts</field><fieldname="res_model"></field><fieldname="view_mode">tree,form</field>rd<menuitemid="configuration_menu"name="Configuration"parent="main_openacademy_menu"/><menuitemid="contact_menu"name="Contacts"parent="configuration_menu"action="contact_list_action"/>nerpInOdoo,arevaluesthatencodeconditionsonrecords.Adomainisalistofcriteriausedtoselectasubsetofamodel'srecords.Eachcriteriaisatriplewithafieldname,anoperatorandavalue.Forinstance,whenusedontheProductmodelthefollowingdomainselectsallserviceswithaunitpriceover1000:[('product_type','=','service'),('unit_price','>',1000)]BydefaultcriteriaarecombinedwithanimplicitAND.Thelogicaloperators&(AND),|(OR)and!(NOT)canbeusedtoexplicitlycombinecriteria.Theyareusedinprefixposition(theoperatorisinsertedbeforeitsargumentsratherthanbetween).Forinstancetoselectproducts"whichareservicesORhaveaunitpricewhichisNOTbetween1000and2000":('product_type','=','service'),'!','&',('unit_price','>=',1000),('unit_price','<',2000)]Adomainparametercanbeaddedtorelationalfieldstolimitvalidrecordsfortherelationwhentryingtoselectrecordsintheclientinterface.eDomainsonrelationalfieldsWhenselectingtheinstructorforaSession,onlyinstructors(partnerswithinstructorsettoTrue)shouldbevisible.openacademy/ysseats=(string="Numberofseats")instructor_id=('',string="Instructor",course_id=('',ondelete='cascade',string="Course",required=True)attendee_ids=('',string="Attendees")AAdomaindeclaredasaliterallistisevaluatedserver-sideandcan'trefertodynamicvaluesontheright-handside,adomaindeclaredasastringisevaluatedclient-sideandallowsfieldnamesontheright-handsideeMorecomplexdomainsCreatenewpartnercategoriesTeacher/Level1andTeacher/Level2.Theinstructorforasessioncanbeeitheraninstructororateacher(ofanylevel).1.ModifytheSessionmodel'sdomain2.Modifyopenacademy/view/togetaccesstoPartnercategories:openacademyopenacademy/seats=(string="Numberofseats")instructor_id=('',string="Instructor",course_id=('',ondelete='cascade',string="Course",required=True)attendee_ids=('',string="Attendees")openacademy/views/<menuitemid="contact_menu"name="Contacts"parent="configuration_menu"action="contact_list_action"/><recordmodel=id="contact_cat_list_action"><fieldname="name">ContactTags</field><fieldname="res_model"></field><fieldname="view_mode">tree,form</field>rd<menuitemid="contact_cat_menu"name="ContactTags"parent="configuration_menu"action="contact_cat_list_action"/><<recordmodel=id="teacher1"><fieldname="name">Teacher/Level1</field>rd<recordmodel=id="teacher2"><fieldname="name">Teacher/Level2</field>rdnerpComputedfieldsanddefaultvaluesSofarfieldshavebeenstoreddirectlyinandretrieveddirectlyfromthedatabase.Fieldscanalsobecomputed.Inthatcase,thefield'svalueisnotretrievedfromthedatabasebutcomputedon-the-flybycallingamethodmethodofthemodel.Tocreateacomputedfield,createafieldandsetitsattributecomputetothenameofamethod.Thecomputationmethodshouldsimplysetthevalueofthefieldtocomputeoneveryrecordinself.selfisacollectionTheobjectselfisarecordset,.,anorderedcollectionofrecords.ItsupportsthestandardPythonoperationsoncollections,likelen(self)anditer(self),plusextrasetoperationslikerecs1+recs2.Iteratingoverselfgivestherecordsonebyone,whereeachrecordisitselfacollectionofsize1.Youcanaccess/assignfieldsonsinglerecordsbyusingthedotnotation,like.importrandomfromopenerpimportmodels,fields,api_name=''name=(compute='_compute_name')@def_compute_name(self):forrecordinself:=str(1,1e6))Thevalueofacomputedfieldusuallydependsonthevaluesofotherfieldsonthecomputedrecord.TheORMexpectsthedevelopertospecifythosedependenciesonthecomputemethodwiththedecorator.ThegivendependenciesareusedbytheORMtotriggertherecomputationofthefieldwheneversomeofitsdependencieshavebeenmodified:fromopenerpimportmodels,fields,api_name=''name=(compute='_compute_name')value=()@('value')def_compute_name(self):forrecordinself:="Recordwithvalue%s"%eComputedComputedfields?AddthepercentageoftakenseatstotheSessionmodel?Displaythatfieldinthetreeandformviews?Displaythefieldasaprogressbar1.AddacomputedfieldtoSession2.ShowthefieldintheSessionview:openacademy/course_id=('',ondelete='cascade',string="Course",required=True)attendee_ids=('',string="Attendees")taken_seats=(string="Takenseats",compute='_taken_seats')@('seats','attendee_ids')def_taken_seats(self):forrinself:ifnot:=else:=*len/openacademy/views/<fieldname="start_date"/><fieldname="duration"/><fieldname="seats"/><fieldname="taken_seats"widget="progressbar"/><labelfor="attendee_ids"/><treestring="SessionTree">fieldname="name"/><fieldname="course_id"/><fieldname="taken_seats"widget="progressbar"/>rdAnyfieldcanbegivenadefaultvalue.Inthefielddefinition,addtheoptiondefault=XwhereXiseitheraPythonliteralvalue(boolean,integer,float,string),orafunctiontakingarecordsetandreturningavalue:name=(default="Unknown")user_id=('',default=lambdaself:objectgivesaccesstorequestparametersandotherusefulthings:??oristhedatabasecursorobject;itisusedforqueryingthedatabase?oristhecurrentuser'sdatabaseid?isthecurrentuser'srecord?oristhecontextdictionary?returnstherecordcorrespondingtoanXMLid?[model_name]returnsaninstanceofthegivenmodeleActiveobjects–Defaultvalues??Definethestart_datedefaultvalueastoday(see).?AddafieldactiveintheclassSession,andsetsessionsasactivebydefault.openacademyopenacademy/_name=''name=(required=True)sseats=(string="Numberofseats")active=(default=True)instructor_id=('',string="Instructor",openacademy/views/<fieldname="course_id"/><fieldname="name"/><fieldname="instructor_id"/><fieldname="active"/><groupstring="Schedule"><fieldname="start_date"/>Odoohasbuilt-inrulesmakingfieldswithanactivefieldsettoFalseinvisible.The"onchange"mechanismprovidesawayfortheclientinterfacetoupdateaformwhenevertheuserhasfilledinavalueinafield,withoutsavingsavinganythingtothedatabase.Forinstance,supposeamodelhasthreefieldsamount,unit_priceandprice,andyouwanttoupdatethepriceontheformwhenanyoftheotherfieldsismodified.Toachievethis,defineamethodwhereselfrepresentstherecordintheformview,anddecorateitwithtospecifyonwhichfieldithastobetriggered.Anychangeyoumakeonselfwillbereflectedontheform.<!--contentofformview--><fieldname="amount"/><fieldname="unit_price"/><fieldname="price"readonly="1"/>#onchange('amount','unit_price')def_onchange_price(self):#setauto-changingfield=*#Canoptionallyreturnawarninganddomainsreturn{'warning':{'title':"Somethingbadhappened",'message':"Itwasverybadindeed",}}Forcomputedfields,valuedonchangebehaviorisbuilt-inascanbeseenbyplayingwiththeSessionform:changethenumberofseatsorparticipants,andthetaken_seatsprogressbarisautomaticallyupdated.eWarningAddanexplicitonchangetowarnaboutinvalidvalues,likeanegativenumberofseats,ormoreparticipantsthanseats.openacademy/=else:=*len/@('seats','attendee_ids')def_verify_valid_seats(self):if<0:returnreturn{'warning':{'title':"Incorrect'seats'value",'message':"Thenumberofavailableseatsmaynotbenegative",}return{'warning':{'title':"Toomanyattendees",'message':"Increaseseatsorremoveexcessattendees",}ModelconstraintsOdooOdooprovidestwowaystosetupautomaticallyverifiedinvariants:and.APythonconstraintisdefinedasamethoddecoratedwith,andinvokedonarecordset.Thedecoratorspecifieswhichfieldsareinvolvedintheconstraint,sothattheconstraintisautomaticallyevaluatedwhenoneofthemismodified.Themethodisexpectedtoraiseanexceptionifitsinvariantisnotsatisfied:fromimport('age')def_check_something(self):forrecordinself:if>20:raiseValidationError("Yourrecordistooold:%s"%#allrecordspassedthetest,don'treturnanythingeAddPythonconstraintsAddaconstraintthatchecksthattheinstructorisnotpresentintheattendeesofhis/herownsession.openacademy/#-*-coding:utf-8-*-fromopenerpimportmodels,fields,api,exceptionsclassCourse:_name='''message':"Increaseseatsorremoveexcessattendees",}@('instructor_id','attendee_ids')def_check_instructor_not_in_attendees(self):forrinself:ifandin:raise("Asession'sinstructorcan'tbeanattendee")SQLconstraintsaredefinedthroughthemodelattribute.Thelatterisassignedtoalistoftriplesofstrings(name,sql_definition,message),wherenameisavalidSQLconstraintname,sql_definitionisaexpression,andmessageistheerrormessage.eAddSQLconstraintsWiththehelpof,addthefollowingconstraints:1.CHECKthatthecoursedescriptionandthecoursetitlearedifferent2.MaketheCourse'snameUNIQUEopenacademy/session_ids=('','course_id',string="Sessions")_sql_constraints=[ptioncheck'CHECK(name!=description)',"Thetitleofthecourseshouldnotbethedescription"),e'UNIQUE(name)',"Thecoursetitlemustbeunique"),]classSession:_name=''eExercise6-AddaduplicateoptionSinceweaddedaconstraintfortheCoursenameuniqueness,itisnotpossibletousethe"duplicate"functionanymore(FormDuplicate).Re-implementyourown"copy"methodwhichallowstoduplicatetheCourseobject,changingtheoriginalnameinto"Copyof[originalname]".openacademy/session_ids=('','course_id',string="Sessions")@defcopy(self,default=None):default=dict(defaultor{})copied_count=(namelikeuCopyof{}%".format)])piedcountnew_name=u"Copyof{}".formatelse:new_name=u"Copyof{}({})".format,copied_count)default['name']=new_namereturnsuper(Course,self).copy(default)_sql_constraints=[ptioncheck'CHECK(name!=description)',Treeviewscantakesupplementaryattributestofurthercustomizetheirbehavior:decoration-{$name}allowchangingthestyleofarow'stextbasedonthecorrespondingrecord'sattributes.ValuesarePythonexpressions.Foreachrecord,theexpressionisevaluatedwiththerecord'sattributesascontextvaluesandiftrue,thecorrespondingstyleisappliedtotherow.Othercontextvaluesareuid(theidofthecurrentuser)andcurrent_date(thecurrentdateasastringoftheformyyyy-MM-dd).{$name}canbebf(font-weight:bold),it(font-style:italic),orany(danger,info,muted,primary,successorwarning).<treestring="IdeaCategories"decoration-info="state=='draft'"decoration-danger="state=='trashed'"><fieldname="name"/><fieldname="state"/></tree>editableEither"top"or"bottom".Makesthetreevieweditablein-place(ratherthanhavingtogothroughtheformview),thevalueisthepositionwherenewrowsappear.seListcoloringModifytheSessiontreeviewinsuchawaythatsessionslastinglessthan5daysarecoloredblue,andtheoneslastingmorethan15daysarecoloredred.Modifythesessiontreeview:openacademy/views/<fieldname="name"></field><fieldname="model"></field><fieldname="arch"type="xml"><treestring="SessionTree"decoration-info="duration<5"decoration-danger="duration>15"><fieldname="name"/><fieldname="course_id"/><fieldname="duration"invisible="1"/><fieldname="taken_seats"widget="progressbar"/>Displaysrecordsascalendarevents.Theirrootelementis<calendar>andtheirmostcommonattributesare:Thenameofthefieldusedforcolorsegmentation.Colorsareautomaticallydistributedtoevents,buteventsinthesamecolorsegment(recordswhichhavethesamevaluefortheir@colorfield)willbegiventhesamecolor.date_startrecord'sfieldholdingthestartdate/timefortheeventdate_stop(optional)recordrecord'sfieldholdingtheenddate/timefortheeventfield(todefinethelabelforeachcalendarevent)<calendarstring="Ideas"date_start="invent_date"color="inventor_id"><fieldname="name"/></calendar>seCalendarviewAddaCalendarviewtotheSessionmodelenablingtheusertoviewtheeventsassociatedtotheOpenAcademy.11.Addanend_datefieldcomputedfromstart_dateanddurationTTiptheinversefunctionmakesthefieldwritable,andallowsmovingthesessions(viadraganddrop)inthecalendarview2.AddacalendarviewtotheSessionmodel3.AndaddthecalendarviewtotheSessionmodel'sactionsopenacademyopenacademy/#-*-coding:utf-8-*-fromdatetimeimporttimedeltafromopenerpimportmodels,fields,api,exceptionsclassCourse:attendee_ids=('',string="Attendees")taken_seats=(string="Takenseats",compute='_taken_seats')end_date=(string="EndDate",store=True,compute='_get_end_date',inverse='_set_end_date')@('seats','attendee_ids')def_taken_seats(self):}@('start_date','duration')def_get_end_date(self):forrinself:ifnotand:=#Adddurationtostart_date,but:Monday+5days=Saturday,so#subtractonesecondtogetonFridayinsteadstart=duration=timedelta(days=,seconds=-1)=start+durationdef_set_end_date(self):forrinself:ifnotand:#Computethedifferencebetweendates,but:Friday-Monday=4days,#soaddonedaytoget5daysinsteadstart_date=end_date==(end_date-start_date).days+1@('instructor_id','attendee_ids')def_check_instructor_not_in_attendees(s
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 板式蒸餾塔的課程設(shè)計(jì)
- 種植小草生活課程設(shè)計(jì)
- 玻璃纖維耐高溫性能研究考核試卷
- 研學(xué)課程設(shè)計(jì)安全隱患
- 電容器在無(wú)人駕駛汽車環(huán)境感知系統(tǒng)中的應(yīng)用考核試卷
- 環(huán)保燃料的可持續(xù)發(fā)展考核試卷
- 油氣田設(shè)備管理與維護(hù)技術(shù)考核試卷
- 皮革服裝生產(chǎn)中的質(zhì)量管理與改進(jìn)考核試卷
- 塑料薄膜在汽車內(nèi)飾材料的運(yùn)用考核試卷
- 波形變換與產(chǎn)生課程設(shè)計(jì)
- SFC15(發(fā)送)和SFC14(接收)組態(tài)步驟
- 旅行社公司章程53410
- 小學(xué)班主任工作總結(jié)PPT
- 起世經(jīng)白話解-
- 螺桿式制冷壓縮機(jī)操作規(guī)程完整
- 頜下腺囊腫摘除手術(shù)
- 五金件成品檢驗(yàn)報(bào)告
- CDN基礎(chǔ)介紹PPT課件
- SPC八大控制圖自動(dòng)生成器v1.01
- 復(fù)晶砂、粉在硅溶膠精密鑄造面層制殼中的應(yīng)用
- 實(shí)驗(yàn)室設(shè)備和分析儀器的確認(rèn)和驗(yàn)證
評(píng)論
0/150
提交評(píng)論