最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

0O00--計算型字段的搜索方法

2023-09-15 01:48 作者:你知道阿基米德原理嗎  | 我要投稿

就拿一個比較常見的需求舉例吧。如果我想跟進某個單據(jù)的進度,想篩選出距其創(chuàng)建起1天內(nèi),2天內(nèi),7天內(nèi)的所有單據(jù),怎么辦?


懶得廢話了。


方案1:

? ? days = fields.Integer() + 定時任務每天+1


方案2:

? ? def _compute_days(selfs):

? ? ? ? _today = date.today()

? ? ? ? for self in selfs:

? ? ? ? ? ? self.days = (_today - self.create_day).days

? ? days = fields.Integer(compute='_compute_days',)

因為系統(tǒng)無法感知到每一天的時間變化,所以就就形成了這樣一個非儲存的計算型的字段。

好吧,其實這個字段建立之初就只是為了用于篩選,我們就去看看非儲存的計算型字段怎么被應用于搜索視圖吧。


def _search_days(cls, operator, value):

? ? operator_lambda = {

? ? ? ? '>': lambda s: s.days > value,

? ? ? ? '>=': lambda s: s.days >= value,

? ? ? ? '=': lambda s: s.days == value,

? ? ? ? '<': lambda s: s.days < value,

? ? ? ? '<=': lambda s: s.days <= value,

? ? }

? ? selfs = cls.search([]).filtered(operator_lambda[operator])

? ? return [('id','in',selfs.ids)]


為這樣非儲存的字段構(gòu)建了一個支持比較的搜索方法,是odoo為我們提供的標準機制。

但問題是,這樣的方法對嗎?好嗎?跟我們該干的事吻合嗎?


回顧一下search屬性的本意吧。

已知現(xiàn)在在業(yè)務層需要對days做篩選,而數(shù)據(jù)庫并不理解這個表的days是什么東西,從而需要odoo后端在中間做過渡,或許轉(zhuǎn)義更貼切一些。


重新再來看看這個search方法,大概率是可行的,走的通的,不夠好的。

因為[('id','in',selfs.ids)]這樣的返回值,早就脫離了轉(zhuǎn)義的范疇。

domain之所以被設計成3元元組的列表結(jié)構(gòu),就是為了體現(xiàn)其中每一個條件的業(yè)務含義,不然倒不如直接接收若干個ids的合集,用來取交集并集補集不是更直接一些?


具體來看,這個搜索方法并不在乎業(yè)務,理論上可以適用于任何字段的搜索需求,完全是依賴其compute方法執(zhí)行后的結(jié)果。這會增加更多本可以避免的計算頻率,更重要的是,這樣的比較脫離了實際業(yè)務,沒有體現(xiàn)對應的映射關(guān)系。


在提一個更好的方法之前,我先來頓理論分析。

search(

? ? [(days, operator, value), ]

)

=>

search(

? ? []

).filtered(

? ? lambda s: operator_lambda(

? ? ? ? s.days, timedelta(days=value)

? ? )

)

=>

search(

? ? []

).filtered(

? ? lambda s: operator_lambda(

? ? ? ? date.today() - s.create_date, timedelta(days=value)

? ? )

)

=>

search(

? ? []

).filtered(

? ? lambda s: operator_lambda(

? ? ? ? date.today() - timedelta(days=value), s.create_date)

? ? )

)

=>

search(

? ? []

).filtered(

? ? lambda s: reverse_operator_lambda(

? ? ? ? s.create_date, date.today() - timedelta(days=value)

? ? )

)

=>

search(

? ? [('create_date', reverse_operator, date.today() - timedelta(days=value)), ]

)

私以為上面的domain推導某種程度某些方面某個時刻是成立的。


def _search_days(cls, operator, value):

? ? target_date = date.today() - timedelta(days=value)

? ? operator_mapping = {

? ? ? ? '>': '<',

? ? ? ? '>=': '<=',

? ? ? ? '=': '=',

? ? ? ? '<': '>',

? ? ? ? '<=': '>=',

? ? }

? ? return [('create_day', operator_mapping[operator], target_date)]


注意到了嗎?我甚至返回的也是一個 不精確 的domain條件,但這樣才好。

為什么?因為當我給你[('state','=','done')]這樣的條件時,你不會糾結(jié)到底是哪幾張單,你也不會去擔心這個問題,因為你大概率覺得這出這些id本就是數(shù)據(jù)庫的工作??刹皇锹??

那又為什么要對這個非儲存的計算型字段高看一眼,替數(shù)據(jù)庫完成它的工作呢?

也許這就是中間層的意義吧。不要打擾它原先的運行機制,包括風格在內(nèi)。?



順便一提,為什么要用一個不存在的create_day而不是create_date來做解釋呢?理論上時間類型也支持timedelta的加減,也可以向前向后推算的不是嗎?

簡而言之,通常我們可以認為date類型屬于一種00:00:00的datetime。正因我如此確定所有單據(jù)都以這樣定死的后綴結(jié)尾,當我們?nèi)ルS機訪問時,我也可以直接利用date.today()構(gòu)建一個0點0分0秒的當天來比對timedelta.days,而不用考慮“尾差”所帶來的timedelta.seconds對days的干擾。然而,當我們以datetime的視角去要求N天(前/時/后)時,以12:00:00為例,我們可以通過domain大致找到那些介于0.5天至1.5天之間的單據(jù)。至于“尾差”部分如何判斷嘛?來人,上filtered。


0O00--計算型字段的搜索方法的評論 (共 條)

分享到微博請遵守國家法律
万源市| 大名县| 禹州市| 吴堡县| 杭锦后旗| 梅州市| 和田县| 论坛| 高雄县| 诸暨市| 武川县| 莎车县| 双鸭山市| 马公市| 武安市| 轮台县| 德昌县| 嘉义县| 关岭| 温州市| 德钦县| 丹江口市| 高州市| 育儿| 南木林县| 江山市| 江北区| 双峰县| 文安县| 裕民县| 灵丘县| 黎川县| 宜章县| 福泉市| 遵化市| 高陵县| 都江堰市| 屏山县| 镇原县| 沙湾县| 桃源县|