Skip to Content
🚀 Odoo开发者快速上手

给 Odoo 开发者的快速上手指南

这个页面专门为有 Python/Odoo 经验的开发者准备。如果你熟悉 Odoo 开发,这里会帮你快速建立 C#/Avalonia 的心智模型。

核心概念映射

Odoo/PythonC#/Avalonia说明
models.Modelclass数据模型定义
fields.Charstring字符串字段
fields.Integerint整数字段
fields.Floatdoubledecimal小数字段
fields.Booleanbool布尔字段
fields.Many2one对象引用关联关系
fields.One2manyList<T>一对多关系
@api.dependsINotifyPropertyChanged属性变化通知
self.env依赖注入(DI)服务访问
XML 视图AXAMLUI 定义
search()LINQ数据查询
create()new创建对象

代码对比示例

1. 定义模型

class Partner(models.Model): _name = 'res.partner' _description = 'Partner' name = fields.Char(string='Name', required=True) email = fields.Char(string='Email') age = fields.Integer(string='Age') is_company = fields.Boolean(string='Is Company') def get_display_name(self): return f"{self.name} ({self.email})"

关键差异:

  • C# 用 { get; set; } 定义属性,不是字段
  • C# 用 ? 表示可空类型(如 string?
  • C# 方法名用 PascalCase(GetDisplayName),Python 用 snake_case(get_display_name

2. 创建记录

# Odoo partner = self.env['res.partner'].create({ 'name': 'Tom', 'email': 'tom@example.com', 'age': 25 })

3. 查询数据

# Odoo partners = self.env['res.partner'].search([ ('age', '>', 18), ('is_company', '=', False) ]) # 获取第一个 first = partners[0] if partners else None # 遍历 for partner in partners: print(partner.name)

关键差异:

  • Odoo 用 domain 语法 [('field', 'op', value)]
  • C# 用 LINQ 的 lambda 表达式 p => p.Age > 18
  • C# 的 FirstOrDefault() 类似 Odoo 的 partners[0] if partners else None

4. 更新记录

# Odoo partner.write({ 'name': 'New Name', 'age': 26 })

5. 删除记录

# Odoo partner.unlink()

语法差异速查

变量声明

# Python - 动态类型 name = "Tom" age = 18 price = 19.99 is_active = True # 可以随时改类型 name = 123 # 合法

条件判断

# Python if age >= 18: print("成年") elif age >= 13: print("青少年") else: print("儿童")

差异:

  • C# 条件必须加括号 ()
  • C# 代码块必须用花括号 {}
  • C# 用 else if,不是 elif

循环

# Python for i in range(5): print(i) for name in names: print(name) while count > 0: count -= 1

函数/方法

# Python def calculate_total(price, quantity): return price * quantity def greet(name="Guest"): return f"Hello, {name}"

差异:

  • C# 必须声明返回类型(doublestring
  • C# 方法名用 PascalCase
  • C# 参数必须声明类型

列表/集合

# Python names = [] names.append("Tom") names.append("Alice") print(len(names)) print(names[0]) # 字典 users = {} users[1] = "Tom" users[2] = "Alice"

思维转换

1. 从动态到静态

Python/Odoo:

  • 运行时才知道类型
  • 灵活但容易出错

C#:

  • 编译时就确定类型
  • IDE 能提前发现错误
  • 代码提示更准确

好处: 大型项目更安全,重构更容易

2. 从 ORM 到手动管理

Odoo:

  • 框架自动处理数据库
  • self.env['model'].search()

C#:

  • 需要选择 ORM(如 Entity Framework)
  • 或者手动写 SQL

好处: 更灵活,性能可控

3. 从服务端到客户端

Odoo:

  • 代码运行在服务器
  • 用户通过浏览器访问
  • 需要网络连接

Avalonia:

  • 代码运行在用户电脑
  • 不需要网络
  • 响应更快

好处: 离线可用,性能更好

4. 从 MVC 到 MVVM

Odoo:

  • Model(模型)
  • View(XML 视图)
  • Controller(Python 控制器)

Avalonia:

  • Model(数据模型)
  • View(AXAML 视图)
  • ViewModel(视图模型,连接 Model 和 View)

核心区别: MVVM 用数据绑定,不需要手动更新 UI

常见困惑解答

Q1: 为什么要写这么多类型?

A: 静态类型能在编译时发现错误。

# Python - 运行时才报错 def add(a, b): return a + b result = add("hello", 5) # 运行时报错
// C# - 编译时就报错 public int Add(int a, int b) { return a + b; } // int result = Add("hello", 5); // 编译错误,提前发现

Q2: 没有 self.env 怎么办?

A: C# 使用依赖注入(Dependency Injection)。

# Odoo partner = self.env['res.partner'].browse(1)
// C# (后面会学) public class MyService { private readonly IPartnerRepository _repo; public MyService(IPartnerRepository repo) { _repo = repo; // 依赖注入 } public Partner GetPartner(int id) { return _repo.GetById(id); } }

Q3: UI 怎么定义?

A: 用 AXAML(类似 Odoo 的 XML 视图)。

<!-- Odoo XML --> <record id="view_partner_form" model="ir.ui.view"> <field name="name">partner.form</field> <field name="model">res.partner</field> <field name="arch" type="xml"> <form> <field name="name"/> <field name="email"/> </form> </field> </record>
<!-- Avalonia AXAML --> <Window xmlns="https://github.com/avaloniaui"> <StackPanel> <TextBox Text="{Binding Name}" /> <TextBox Text="{Binding Email}" /> </StackPanel> </Window>

Q4: 数据库怎么操作?

A: 用 Entity Framework Core(类似 Odoo ORM)。

# Odoo partners = self.env['res.partner'].search([('age', '>', 18)])
// C# Entity Framework var partners = dbContext.Partners .Where(p => p.Age > 18) .ToList();

学习路径建议

Week 1-2: 适应 C# 语法

  • 最痛苦的阶段
  • 习惯静态类型
  • 习惯花括号和分号
  • 对应 Odoo: 类似刚学 Python 时的语法适应期

Week 3-4: 理解 OOP

  • 类、对象、继承
  • 对应 Odoo:models.Model 类似

Week 5-6: 学习 MVVM

  • 数据绑定
  • 命令模式
  • 对应 Odoo: 类似 Odoo 的 MVC,但更自动化

Week 7-8: 数据持久化

  • Entity Framework
  • LINQ 查询
  • 对应 Odoo: 类似 Odoo ORM

Week 9-12: 综合项目

  • 完整的桌面应用
  • 对应 Odoo: 类似开发一个完整的 Odoo 模块

快速记忆技巧

命名转换规则

Python/OdooC#示例
snake_casePascalCase(类、方法)get_nameGetName
snake_casecamelCase(变量)user_nameuserName
_nameName私有变量用 _name,属性用 Name

类型对照表

PythonC#备注
strstring字符串
intint整数
floatdouble小数
boolbool布尔
listList&lt;T&gt;列表
dictDictionary<K,V>字典
setHashSet&lt;T&gt;集合
Nonenull空值

常用操作对照

操作PythonC#
打印print()Console.WriteLine()
输入input()Console.ReadLine()
字符串格式化f"{name}"$"{name}"
列表长度len(list)list.Count
字符串长度len(str)str.Length
类型转换int(s)int.Parse(s)
安全转换-int.TryParse(s, out int n)

记住: C# 不是更难,只是更严格。一旦习惯了静态类型,你会发现它能帮你避免很多运行时错误。

下一步

  1. 从 Week 1 Day 1 开始学习
  2. 遇到概念不清楚时,先按这个对照表找到 C# 和 Odoo 的对应关系
  3. 每学完一个概念,想想它在 Odoo 里的对应物
  4. 不要急,前两周最难,坚持过去就好了

重要提示: 不要试图用 Python 的思维写 C#。接受 C# 的方式,你会发现它的优势。