python odoo随笔

   整理一下用到的内容,想到什么写什么吧,还在完善中

odoo接口

controller

继承odoo的http中controller模型,对函数使用router装饰器

route的参数

route: 路由
type: json或者http
auth: 
	public: 公开接口,可以直接调用,用户身份为public
	user: 内部用户,需要登录才能调用
	none: 公开接口,但没有用户,无法访问数据库
method: GET/POST/HEAD等
cors: *
csrf: False

发送请求

使用python的Request包,不多说了

odoo定时任务

创建定时任务,也就是往ir.cron中增加记录,可以通过xml加载data或者界面上手动添加,是action的一种

主要参数

name:名称
interval_number: 间隔次数,数字类型,和间隔单位共同组成间隔时间,例如:3 days
interval_type: minutes, hours, days, weeks, months
numbercall:执行次数:-1表示无限执行
doall: 服务重启是否去做漏掉的数据
model_id:调用的方法的模型,模块.模型
code: 调用的方法,model.do_xxx()

odoo model三种继承

  1. _inherit = “A” 原模型继承,直接修改原表,共享方法和数据
  2. _inherit = “A” 且 _name = “B” 原型继承,相当于复制一份A表,重命名为B,并进行修改
  3. 给many2one字段加上 delegate=True 属性,委托继承,这个many2one字段进行增加时,会操作关联的表的数据

odoo view的继承

新建view,并且加上 inherit_id 属性指向继承的原视图,然后使用xpath定位元素进行修改。
注意:
ref指向的视图ID,格式为【模块名.视图ID】,这样当指向不同的模块的视图时才能找到,否则只会在当前模块下找
如果通过action去展示新的view,需要加上 view_id 属性,指向新的view的id,否则不会正常显示

odoo action

act_window:

可以在xml里定义绑定到菜单上,python方法里也可以返回,写好对应的参数,也会打开相应的页面

url_action

python方法中返回,打开设置的url地址

{
    "type": "ir.actions.act_url",
    "url": "https://odoo.com",
    "target": "self",     # target为new的话会打开新的页面
}

action_server

效果是在tree,form视图的动作按钮下拉框中增加功能

<record model="ir.actions.server" id="print_instance">
    <field name="name">Res Partner Server Action</field>
    <field name="model_id" ref="model_res_partner"/>
    <field name="binding_model_id" ref="model_res_partner"/>
    <field name="binding_view_types">list,form</field>
    <field name="state">code</field>
    <field name="code">
        if record.some_condition():
            action = {
                "type": "ir.actions.act_window",
                "view_mode": "form",
                "res_model": record._name,
                "res_id": record.id,
            }
    </field>
</record>

report_action

创建报告动作,下面和report一起写

ir_corn

定时任务,上面写过了

odoo report

odoo打印报表功能,自定义一个报告模板template,然后可以通过python方法来render这个模板,或者写个report_action来提供触发

<record id="print_portfolio_report" model="ir.actions.report">
	<field name="model">portfolio</field> <!--绑定的模型-->
	<field name="name">Portfolio Report</field>
	<field name="report_name">practice.portfolio_report_template</field>  <!--使用的报告模板-->
	<field name="report_type">qweb-pdf</field>
	<field name="binding_model_id" ref="model_portfolio"/> <!--报告这个action绑定到哪个模型上,这个模型的视图的动作按钮旁边会出现一个打印按钮-->
	<field name="binding_type">report</field>
</record>

<template id="portfolio_report_template">
    <t t-name="portfolio_report_template">
        <t t-call="web.html_container"> <!--t-call继承别的模板-->
            <t t-call="web.external_layout">
                <div class="page"> <!--加一个page-->
                    <h2 align="center">
                        <span>作品集统计</span>
                    </h2>
                        <table class="table table-condensed table-bordered table-striped" style="text-align: center"
                               boder="1">
                            <thead>
                                <tr>
                                    <th>名称</th>
                                    <th>描述</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr t-foreach="docs" t-as="line">
                                    <td>
                                        <span t-esc="line.name"/>
                                    </td>
                                    <td>
                                        <span t-esc="line.description"/>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                </div>
            </t>
        </t>
    </t>
</template>

以上xml不要忘了在mainifest中加载

如果要对数据做很多其他处理,需要写一个report模型,继承瞬态类,并实现_get_report_values方法,详细可参考odoo14生成PDF报告

odoo search视图

<record id="xxx_view_search" model="ir.ui.view">
    <field name="name">xxx_view_search</field>
    <field name="model">xxx.xxx</field>
    <field name="arch" type="xml">
        <search>
            <field name="xxx"/>
            <field name="xxx1"/>
            <separator/>
            <filter string="待办" name="todo" domain="[()]"/>
            <searchpanel>
			   	<field name="xxx" string="XXX" enable_counters="1"/>
			</searchpanel>
			<group expand="0" string="Group By">
                <filter string="Xxx" name="group_by_xxx" domain="[]"
                        context="{'group_by': 'xxx_id'}"/>
            </group>
        </search>
    </field>
</record>

field

field中添加的字段,将会在上面的搜索栏下拉框中显示,也就是你输入 123,会出现让你选择xxx=123或者xxx1=123的选项

filter

filer是写一个domain,将会增加在tree视图上方的筛选中,同时如果你希望进入tree视图默认有某个过滤条件,就可以写了filter之后,在act_window里传入context,格式:“search_default_过滤器的name”:1

<field name="search_view_id" ref="xxx_view_search"/>
<field name="context">{"search_default_todo":1}</field>

group

这个标签里分组内容,会出现在tree视图上方的分组下拉框中
增加filter,配上context=“{‘group_by’: ‘xxx_id’}”,会以xxx_id为依据对tree视图进行分组,如果想进入tree视图时默认分组,也是在act_widow里的context增加

<field name="search_view_id" ref="xxx_view_search"/>
<field name="context">{"search_default_group_by_xxx":1}</field>

searchpanel

这个标签里你增加的字段,将会作为分组依据,在tree视图左边划出一块区域做树状图,进行分层级,enable_counter 设为 1,会计算每个组的数目

odoo wizard

odoo 自定义widget

直接引用链接吧,感觉写的挺好 odoo自定义widget
基本思路就是写js,xml里导入js文件,视图里引用widget

钩子函数

写在模块的init文件中,在manifest中进行调用,有以下三种:
pre_init_hook:安装模块前执行
post_init_hook:安装模块后执行
uninstall_hook:卸载模块后执行

from odoo import api, SUPERUSER_ID, _

def uninstall_hook(cr, registry):
    """
    数据初始化,卸载时执行
    """
    env = api.Environment(cr, SUPERUSER_ID, {})
    ir_config = env["ir.config_parameter"].sudo()
    ...

FASTAP

高性能的异步web框架

uvicorn:ASGI服务器,用来构建异步web服务,使用asyncio 库实现异步 I/O 操作
starlette:构建中间件,amount静态资源等
pydantic:构建数据结构,规范接口文档
fastapi:异步web服务框架,可以自动生成接口文档

大致思路如下

app = FastAPI(
    docs_url="/docs",
    on_startup=[database_connect, ],
    on_shutdown=[database_disconnect, ]
)

def main():
    uvicorn.run(app=app, host="0.0.0.0", port=8000)

MQTT

物联网传输协议,用于轻量级的实时消息发布/订阅消息传输
主要结构是发布者,代理和订阅者

基本使用:

  1. 启动mqtt server(broker)
  2. 建立mqtt client并进行pubulish和subscribe,推送和订阅不同的topic消息
    不同的topic可以设定不同的qos
    qos:0 表示只管发送不管是否重复和送到
    qos:1 表示保证送到至少一次
    qos:2 表示确保送到且只有一次
    可设置的方法一般有on_connect,on_message,on_disconnect,设置回调函数,在触发这些动作的时候就会进行调用

多进程使用

通过multiprocessing包来实现,创建process对象,target调用方法,args传递参数,daemon设置是否为守护进程,守护进程随着主进程结束而结束,独立后台运行,一般实现web服务,数据库服务,定时清理之类的功能

Queue可以用来通信,在子进程中q.put(),在另一个进程中就可以q.get()

q = Queue()

p = Process(target=fun_test, args=(q,), daemon=True)
p.start()
p.join()

多线程使用

一般线程和进程很类似,调用threading库,也是target调用方法,args传参数,守护线程会在当前进程的所有非守护线程执行完毕之后挂掉
参考python多线程

t = threading.Thread(target=job, args=(data[i], q))

也可以使用线程池 ThreadPoolExecutor
先submit()提交任务到线程池,再使用as_complete()取出所有任务的结果,用task.result()来获取结果

with ThreadPoolExecutor(max_workers=8) as executor:
	task_list = [executor.subumit(func,args) for i in range(10)]
	
    for task in as_completed(task_list):
       task_exception = task.exception()
       if task_exception:
           _logger.error("任务执行失败: %s", ustr(task_exception))
           continue
       data.append(task.result())

协程使用

通过async 和 await 来实现异步,await执行的方法必须是async方法,async方法中也必须有await调用

要运行协程需要创建一个event_loop对象,在主线程中直接get就可以,子线程就需要先set一个了。loop.run_until_complete表明会阻塞到coroutine执行完毕再结束

def async_main():
	exec_list = [x for x in range(1, 6)]
    task_list = []  # 任务列表
    for x in exec_list:
        task = asyncio.create_task(parseNode(x, x))
        task_list.append(task)  # 将每个任务都放入任务列表

    for y in task_list:
        await y  # 使主线程等待每个任务执行完成
        
loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, ask_exit)
loop.add_signal_handler(signal.SIGTERM, ask_exit)
loop.run_until_complete(async_main())

python 生成器和迭代器

用iter(obj)可以将一个可迭代对象变成迭代器,然后可以对这个迭代器进行next()调用

生成器是在函数中加入yield关键字,yield的作用是阻塞和return,直到next()调用这个生成器的时候,会再次执行到yield,说白了相当于打断点

python 装饰器和闭包

PGSQL

  • 13
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值