Category: Development

Odoo12 开发之重写List记录打开方式

在Odoo中,记录的打开方式都是通过事件绑定的方式进行的,但要如何才能知道我在点击这个记录的时候触发了什么操作呢。这篇日志主要就是说明一下,在遇到这类情况的时候如何来找到正确的处理方式。

首先我们得到明确的需求,我们需要在Odoo的列表视图中重写打开记录指向的Form。

Odoo 列表视图

一、准备工作

进入Assets Debug模式

或者使用修改Url的方式

 http://localhost:8069/web?debug=assets#home

进入浏览器开发者模式(F12)

Chrome Debug

二、找寻需要的事件

事件管理

如果事件太多可以使用如下方式移除不必要的事件

接下来我们可以将不必要的实践移除后再点击行记录,如果能正确执行,那么代表我们需要的事件就还在这个列表中。

最终在我移除了大部分事件后,保留如下事件的情况下,功能还正常。那么可以断定,我需要的点击事件就是它。

跟进Js代码中,发现这个代码是这样的

proxy: function (method) {
        var self = this;
        return function () {
            var fn = (typeof method === 'string') ? self[method] : method;
            if (fn === void 0) {
                throw new Error("Couldn't find method '" + method + "' in widget " + self);
            }
            return fn.apply(self, arguments);
        };
    },

从代码中可以看出,这又是一个代理事件,那么继续打断点跟踪

最终在list_renderer.js文件见找到如何方法

    _onRowClicked: function (event) {
        // The special_click property explicitely allow events to bubble all
        // the way up to bootstrap's level rather than being stopped earlier.
        if (!$(event.target).prop('special_click')) {
            var id = $(event.currentTarget).data('id');
            if (id) {
                this.trigger_up('open_record', { id: id, target: event.target });
            }
        }
    }

再看方法引用

至此,就可以直接复写该方法来实现了。。

附上最后实现的代码~

odoo.define('ps.web.ListRenderer', function (require) {
"use strict";
var ListRenderer = require('web.ListRenderer');

ListRenderer.include({
		_onRowClicked: function (event) {
			if (this.state.model === 'combined.statements.working.paper.project') {
				let record = this.state.data.find(record => record.id === $(event.currentTarget).data('id')).data;
				this.do_action({
					type: "ir.actions.client",
					tag: 'working.papers',
					params: record
				});
			}else{
				this._super.apply(this, arguments);
			}
		}
	});
});

PostgreSql 常用操作

PostgreSQL Client Applications

  • clusterdb — cluster a PostgreSQL database
  • createdb — create a new PostgreSQL database
  • createuser — define a new PostgreSQL user account
  • dropdb — remove a PostgreSQL database
  • dropuser — remove a PostgreSQL user account
  • ecpg — embedded SQL C preprocessor
  • pg_basebackup — take a base backup of a PostgreSQL cluster
  • pgbench — run a benchmark test on PostgreSQL
  • pg_config — retrieve information about the installed version of PostgreSQL
  • pg_dump — extract a PostgreSQL database into a script file or other archive file
  • pg_dumpall — extract a PostgreSQL database cluster into a script file
  • pg_isready — check the connection status of a PostgreSQL server
  • pg_receivewal — stream write-ahead logs from a PostgreSQL server
  • pg_recvlogical — control PostgreSQL logical decoding streams
  • pg_restore — restore a PostgreSQL database from an archive file created by pg_dump
  • psql — PostgreSQL interactive terminal
  • reindexdb — reindex a PostgreSQL database
  • vacuumdb — garbage-collect and analyze a PostgreSQL database

登陆控制台

psql -U postgres -h localhost -W -d baseName

一、用户和权限管理

# 可以使用 \h CREATE ROLE 查看语法
CREATE ROLE rolename;
CREATE USER username;

# 例子
CREATE USER jalena WITH CREATEDB LOGIN PASSWORD 'jalena';

当然还可以直接使用客户端工具直接创建。 createuser --interactive

CREATE USER和CREATE ROLE的区别在于,CREATE USER指令创建的用户默认是有登录权限的,而CREATE ROLE没有。

# 修改用户权限
ALTER USER jalena WITH NOCREATEDB; # 取消数据库创建权限
ALTER USER jalena WITH PASSWORD 'password'; # 修改密码

定义存取权限

# 授予jalena对demo库所有的权限
GRANT ALL PRIVILEGES ON DATABASE demo TO jalena;

# 只授予某个权限
GRANT UPDATE ON DATABASE demo TO jalena;
GRANT SELECT ON ALL TABLES IN SCHEMA PUBLIC TO jalena;

# 特殊符号《ALL》代表所有权限,《PUBLIC》代表所有用户
GRANT ALL ON demo TO jalena; # 赋给用户所有全选
GRANT SELECT ON demo TO PUBLIC; # 将SELECT权限赋予所有用户

二、备份

PostgreSql提供了2个备份命令,分别为pg_dump和pg_dumpall,这种方式可以在数据库正在使用的时候进行完整一致的备份, 并不阻塞其它用户对数据库的访问。

使用说明可以使用pg_dump --help查看。

pg_dump -F c -f <filename.dmp> -C -E UTF-8 -U <DataBaseUser> <DataBaseName>
pg_dumpall -U postgres -F c -c -f all.dmp

三、恢复

CREATE USER jalena WITH CREATEDB PASSWORD 'password';
CREATE DATABASE demo OWNER jalena;
GRANT ALL PRIVILEGES ON DATABASE odam to inspur;

pg_restore -j5 -U <DBUSER> -W -d <DBNAME> -v <FILEPATH>

四、表与文件之间的拷贝

postgresql提供了COPY命令用于表与文件(标准输出、标准输入)之间的相互拷贝,COPY TO由表至文件,COPY FROM由文件至表。

# 将整张表拷贝至标准输出
copy res_users to stdout;

# 将表的部分字段拷贝至标准输出,且输出字段名称,字段间使用','分割
copy res_users(id,login) to stdout delimiter ',' csv header;

# 将查询结果拷贝至标准输出
copy(select id,login from res_users) to stdout delimiter '|' quote '"' csv header;

将标准输入拷贝至表中需要注意几点

  1. 字段间分割符默认使用【Tab】键
  2. 换行使用回车键
  3. 结束使用反斜线加英文标点(\.)
  4. 指定字段顺序,不然会出现错误的赋值
#将标准输入拷贝至表中
copy res_users(id,login) from stdin;
>> 1	login1
>> 2	login2
>> \.

# 从标准输入拷贝至表中,并将标准输入第一行作为字段名,字段分隔符为','
copy res_users(id,login) from stdin delimiter ',' csv header;
>> 1,login1
>> 2,login2
>> \.

以上是表与标准输入、输出之间的相互拷贝,表与文件的拷贝和以上完全相同,只是将标准输入、输出换成文件。需要注意的是

  1. 数据库用户必须有文件所在路径的写权限
  2. 如果表存在中文字符,导出至csv文件时需要设置编码为GBK,否则使用excel打开中文显示乱码
  3. 将文件导入表中时任然需要考虑编码问题
# 将表拷贝至csv文件中
copy res_users to 'D:/res_users.csv' delimiter ',' csv header;

# 以GBK编码拷贝到cvs文件
copy res_users to 'D:/res_users.csv' delimiter ',' csv header encoding  'GBK';
# 将文件导入至表中
copy res_users from 'd:/res_users.csv' delimiter ',' csv header encoding 'GBK';

五、PSQL常用命令

-- 查看所有psql可执行的命令
\?

-- 退出控制台
\q

-- 退出当前执行命令
q

-- 更改当前工作目录
\cd [目录]

-- 从文件中执行命令
\i 文件

-- 列出全部数据库
\l

-- 列出全部序列
\ds

-- 切换当前数据库到指定的数据库
\c [database_name]

-- 显示所有的表
\dt

-- 显示指定的表的结构
\d [table_name]

-- 显示视图
\dv

-- 列出全部用户
\du or \dg

-- 列出当前数据库和连接的信息
\conninfo

-- 修改用户密码
\password uesrname

Postgres 日志分析

最近在项目开发过程中发现客户方总是出现卡顿,数据服务器峰值出现驼峰的情况,所以需要分析数据库日志,且ODOO使用的是 Postgres  的数据库,靠眼睛去看那是分析不出啥的。

pgBadger乃是 Postgres 的一个分析工具

项目地址:https://github.com/darold/pgbadger

yum install -y pgbadger
which pgbadger
pgbadger postgresql-* -f syslog

命令执行完成后,会在当前命令执行目录生成一个out.html的文件。

Python 转数字为Excel列,转列为数字

def convent_column_to_char(column):
	"""
	将数字转换为Excel列
	1 => A, 2 => B, ......, 27 => AA
	:param column: int
	:return: str
	"""
	if not isinstance(column, int):
		return column
	tStr = str()
	while column != 0:
		res = column % 26
		if res == 0:
			res = 26
			column -= 26
		tStr = chr(ord('A') + res - 1) + tStr
		column = column // 26
	return tStr


def colname_to_num(colname):
	if not isinstance(colname, str):
		return colname
	col = 0
	power = 1

	for i in range(len(colname) - 1, -1, -1):
		ch = colname[i]
		col += (ord(ch) - ord('A') + 1) * power
		power *= 26
	return col


if __name__ == "__main__":
    l = list()
    n = list()
    for a in range(1, 1001):
        l.append(convent_column_to_char(a))
    print(l)
    for a in l:
        n.append(colname_to_num(a))
    print(n)

Odoo 10 Could not execute command lessc

这个问题出现的十分突然,早上打开项目,直接抛出“Could not execute command lessc”这个Error,导致界面加载异常。

现将处理过程做一次分析整理。

再看系统环境变量

启动程序,问题依旧。。

跟进代码

发现 os.environ 这个变量中的PATH里面被覆盖了。

调整启动配置

再次跟进代码
Over...

Archives