odoo二次開發小知識點

1.model屬性

每個對象(即class)一般由字段(變量)和函數組成,每個對象對應着數據庫中的一張表,駝峯命名方式

  • models.Model

      基礎模塊,會根據字段和模型名在後臺數據庫生成對應得表文件

  • models.TransientModel

      臨時模塊,用於彈出信息的臨時數據,會在後臺生成對應得表,但是表的內容根據配置,一定時間後被清除,不會長時間保存,如嚮導時用

  • models.AbstractModel

      抽象模塊,類似於抽象類,常用於繼承



2.model字段類型

    odoo對象支持的字段類型有

    基礎:char,text,boolean,integer,float,date,datetime,binary

    複雜:selection,function

    關係:one2one,many2one,one2many,many2many



3.self

self是什麼,目前舊版本中使用的self是對,遊標cr,用戶id,上下文context,模型,記錄集,緩存的封裝

可以通過self.xx獲取到這些封裝得東西,如self.cr,self.uid


在查出來某模型的記錄後可以通過record.xx=value來直接修改記錄的字段內容,同樣在重寫模型的write方法

中,也可以通過self.xx=value來指定新增記錄中某字段得值

此時注意

    a修改查出來的記錄字段值來改變數據庫內容,是通過改變緩存中的值觸發數據庫寫記錄來達到的

    b重寫write方法是,在write方法中每調用一次self.xx=value語句,都會觸發數據庫的寫操作,因此一般用

for rec in self
    rec.xx = xx

   操作

  • 操作緩存:

環境存儲了模型的緩存記錄,因此可以通過環境來獲取增加,修改,刪除記錄,而觸發數據庫更改

從而達到操作數據庫的目的

  如 新增:

    self.env['模型'].create(vals)

         訪問當前用戶:

    self.env.user

          更新緩存,觸發數據庫操作

    self.env.invalidate_all()
  • self常用接口

     普通查詢:返回記錄集,後續通過修改記錄值來觸發數據庫修改

    self.search(domain) #從當前模型的self中查詢
    self.env['model'].search(domain) #獲取某個model的環境,查詢其中的記錄集

           

     只讀查詢:返回列表,只能提取內容,不能觸發數據庫修改

    self.search_read([],['要查詢的字段'])

           

          統計數量:返回符合條件的記錄條數

    self.search_count(domain)


          瀏覽:通過一系列的id值,返回對應得記錄集

    self.browse([id])

          刪除:

    self.unlink(domain)

          

  • new ids

      odoo在創建一個新紀錄時,會使用models.ids虛擬一個記錄id,可以通過如下來判斷

    if is instance(record.id,models.NewId)

記錄集

model的數據是通過數據集的形式來使用的,定義在model裏的函數執行時他們的self變量也是一個數據的集合

class AModel(models.Model):
    _name = 'a.model'
    
    def a_method(self):        # self can be anywhere between 0 records and all records in the database
        self.do_operation()        
    
    def do_operation(self):
    print self # => a.model(1, 2, 3, 4, 5)
    
    for record in self:
        print record # => a.model(1), then a.model(2), then a.model(3), ...

獲取有關聯的字段(one2many,many2one,many2many)也是返回一個數據集合,如果字段爲空則返回空的集合



每個賦值語句都會觸發數據庫字段更新,同時更新多個字段時可使用或者更新多條記錄時使用write函數

# 3 * len(records) database updates
for record in records:
    record.a = 1
    record.b = 2
    record.c = 3
    
# len(records) database updates
for record in records:
    record.write({'a': 1, 'b': 2, 'c': 3})
    
# 1 database update
records.write({'a': 1, 'b': 2, 'c': 3})
  • 數據緩存和預讀取

    odoo會爲記錄保留一份緩存,他有一種內置的預讀取機制,通過緩存來提升性能

  • 集合運算符

  • record in set 返回record是否在set中,record須爲單條記錄,record not in set 反之

  • set1<=set2返回set1是否爲set2的子集

  • set1>=set2返回set2是否爲set1的子集

  • set1|set2返回set1和set2的並集

  • set1&set2返回set1和set2的交集

  • set1-set2返回在集合set1中但不在set2的記錄

  • 其他集合運算

  • filtered()返回滿足條件的數據集

# only keep records whose company is the current user's
records.filtered(lambda r: r.company_id == user.company_id)

# only keep records whose partner is a company
records.filtered("partner_id.is_company")
  • sorted()返回根據提供的鍵排序之後的結果

# sort records by name
records.sorted(key=lambda r: r.name)
  • mapped()返回應用了指定函數之後的結果集

#returns a list of summing two fields for each record in th set
records.mapped(lambda r:r.field1 + r.field2)

#函數也可以是字符串 對應記錄的字段
#return a list of names
records.mapped('name')

#returns a recordset of partners
record.mapped('partner_id')


運行環境

    運行環境保存了很多ORM相關的變量:數據庫查詢遊標,當前用戶,元數據,還有緩存,所有的model數據集都有不可改變的環境變量,可使用env來訪問,如records.env.user,records.env.cr,records.env.context,運行環境還可用於爲其他模型初始化一個空的集合並對該模型進行查詢

self.env['res.partner'].search([['is_company','=',True],['customer','=',True]])
#res.partner(1,2,3,4,5,7,77)
  • 更改運行環境:可以基於一個運行環境自定義,以得到擁有新運行環境的數據集


  • sudo()使用現有數據集創建一個新運行環境,得到一個基於新運行環境的數據集的拷貝

#create partner object as administrator
env['res.partner'].sudo().create({'name':"A Partner"})

#list partners visible by the "public" user
public = env.ref("base.public_user")
env['res.partner'].sudo(public).search([])


  • with_context

一個參數時可用於替換當前運行環境的context,多個參數時通過keyword添加到當前運行環境context或單參數時設置context


  • with_env()完整替換當前運行環境


常用ORM函數

  • search(domain)

    作用:搜索指定domain的記錄集,接受domain表達式參數

  參數:搜索domain[()]

   返回值:符合搜索結果的對象列表,可以通過limit,offset參數返回一個子集,還可以通過order參數對數據排序

self.search([('is_company','=',True),('customer','=',True)])
#res.partner(1,2,3,4,5,7,77)

self.search([('is_company','=',True)],limit=1).name
#'Agrolait'

students = self.search[('name','=',self.name)]
#查所有與當前名字相同的學員

如果只需要知道滿足條件的數據數量,可以使用search_count()函數


  • create(val)

    接收多個字段,值的組合,返回新創建的數據集

作用:創建對象

參數:要創建的對象字典

返回值:新創建的對象

student = self.create({
        'name':'張三'
        'age':26,
        'sex':'man',
        'sno':'1'
})
#創建了一個新學員

self.create({'name':'new name'})


  • write(val)接收多個字段,值組合,會對指定數據集的所有記錄進行修改,不返回

作用:修改對象

參數:需要修改參數的字典

self.write({'name':'new name'})


  • browse(ids)根據數據的id或者一組id來查找,返回符合條件的數據集合

作用:獲取指定記錄的對象

參數:記錄值的ids

返回值:對象列表

browse方法其實在v7版本中應用的更多,因爲v7版本的search等方法返回值是ids,而v8版本中的返回值已經是目標對象的列表了,因此就不需要再次調用browse方法

sale_order = self.env['sale.order'].browse(1) #獲取數據庫中id爲1的銷售訂單

self.browsw([7,8,12])
res.partner(7,8,12)


  • unlink()

作用:刪除記錄

self.unlink

於v7版本每種方法都需要添加cr,uid,ids,context等幾個參數


  • exists()得到某個數據集中保留在數據庫中的那部分,或在對一個數據集進行處理後重新賦值


if not record.exists():
    raise Exception('The record has been deleted')

records.may_remove_dome()
#only keep records which were not deleted
records = records.exists()


  • ref()運行環境函數根據提供的external id返回對應得數據記錄

env.ref('base.group_public')
res.groups(2)


ensure_one()檢驗某個數據集是否只包含單條數據,若不是則報錯

records.ensure_one()
#和下面語句效果相同
assert len(records) == 1,'Expected singleton'


















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章