odoo16入门教程第四章 模型和基本的字段

第四章 模型和基本的字段

在前一章的末尾,我们能够创建一个Odoo模块,不过,到现在为止它依然是一个空壳不能存储任何数据。在我们的房地产模块中,我们想在数据库里存储跟房屋有关的数据,比如名字,描述,价格,使用面积,Odoo 框架提供了便于跟数据交互的工具。

在继续学习之前,确认estate模块已经被安装,也就是说它必须出现在已经安装的应用列表中。

Warning

Do not use mutable global variables.

不要使用可变的全局变量。

单个Odoo实例可以在同一个python进程中并行运行多个数据库。这些数据库可能会安装不同的模块,因此我们不能依赖将根据安装的模块更新的全局变量。(没看懂)

Object-Relational Mapping

参考: 关于这个主题的文档可用在这里找到 Models API.

目标: 这一章节的最后,estate_property表应该被创建

$ psql -d rd-demo
rd-demo=# SELECT COUNT(*) FROM estate_property;
count
-------
    0
(1 row)

Odoo一个关键的组件就是 ORM 层,该层避免人工写大量的sql并且提供了扩展和安全服务。

商业目标被声明为继承Model类的python类,会被自动的集成到持久化系统。

模型可用在他们的定义中通过设置属性进行配置,最重要的属性是_name, 它是必填项,在Odoo系统中定义了模型的名字,这里是一个关于模型最简单的定义。

from odoo import models

class TestModel(models.Model):
    _name = "test.model"

这个定义已经足够让ORM生成一个名字叫test_model的数据表。 _name中的“.”会被ORM自动的转换成“—”,通常来说所有的模型都在一个模型目录中被定义,而且每个模型都定义在自己的python文件中。

现在看看crm_recurring_plan是怎么被定义的,并且相关文件是怎么被引入的?

1、文件定义

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import fields, models


class RecurringPlan(models.Model):
    _name = "crm.recurring.plan"
    _description = "CRM Recurring revenue plans"
    _order = "sequence"

    name = fields.Char('Plan Name', required=True, translate=True)
    number_of_months = fields.Integer('# Months', required=True)
    active = fields.Boolean('Active', default=True)
    sequence = fields.Integer('Sequence', default=10)

    _sql_constraints = [
        ('check_number_of_months', 'CHECK(number_of_months >= 0)', 'The number of month can\'t be negative.'),
    ]

2 引入上面这个文件

#crm/models/__init__.py
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import res_users
from . import calendar
from . import crm_lead
from . import crm_lost_reason
from . import crm_stage
from . import crm_team
from . import res_config_settings
from . import res_partner
from . import digest
from . import crm_lead_scoring_frequency
from . import utm
from . import crm_recurring_plan    #注意这里

3 引入模型文件目录

# crm/__init__.py
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import controllers
from . import models    # 注意这里
from . import report
from . import wizard

from odoo import api, SUPERUSER_ID

练习:

定义estate.property model.

对python文件的修改都需要重启Odoo服务,当我们重启服务的时候,可用使用-u 选项

-u estate 意思是我们想升级estate模块,也就是说ORM将数据模型的变化同步到数据库中,-d 指定数据库,

-u 和-d总是组合在一起使用。

在启动过程中,我们发现两条报警:

...
WARNING rd-demo odoo.models: The model estate.property has no _description
...
WARNING rd-demo odoo.modules.loading: The model estate.property has no access rules, consider adding one...
...

如果是这种情况,那很好,你可用通过psql来检测表有没有被创建。

练习:

Add a description.

Add a _description 避免其中一条报警。

模型字段

参考: 关于这个主题的文档在这里 Fields API.

字段被用来定义模型能够存储什么和存储在什么位置,字段被定义为model类的属性。

from odoo import fields, models

class TestModel(models.Model):
    _name = "test.model"
    _description = "Test Model"

    name = fields.Char()

name字段是一个字符串,它将被表现为python的unicode字符串和数据库里的varchar类型。

类型

目标: 在这一章节的末尾,几个基本的数据类型字段应该被加到estate_property:

$ psql -d rd-demo

rd-demo=# \d estate_property;
                                            Table "public.estate_property"
    Column       |            Type             | Collation | Nullable |                   Default
--------------------+-----------------------------+-----------+----------+---------------------------------------------
id                 | integer                     |           | not null | nextval('estate_property_id_seq'::regclass)
create_uid         | integer                     |           |          |
create_date        | timestamp without time zone |           |          |
write_uid          | integer                     |           |          |
write_date         | timestamp without time zone |           |          |
name               | character varying           |           |          |
description        | text                        |           |          |
postcode           | character varying           |           |          |
date_availability  | date                        |           |          |
expected_price     | double precision            |           |          |
selling_price      | double precision            |           |          |
bedrooms           | integer                     |           |          |
living_area        | integer                     |           |          |
facades            | integer                     |           |          |
garage             | boolean                     |           |          |
garden             | boolean                     |           |          |
garden_area        | integer                     |           |          |
garden_orientation | character varying           |           |          |
Indexes:
    "estate_property_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "estate_property_create_uid_fkey" FOREIGN KEY (create_uid) REFERENCES res_users(id) ON DELETE SET NULL
    "estate_property_write_uid_fkey" FOREIGN KEY (write_uid) REFERENCES res_users(id) ON DELETE SET NULL

有两大类字段:

简单字段,作为原子类型的值直接存储在模型的数据表中

关系字段:关联到自己或者其他模型的记录上。

简单字段类型有 Boolean, Float, Char, Text, Date and Selection.

练习

将下面的字段加到Real Estate Property table.

FieldType
nameChar
descriptionText
postcodeChar
date_availabilityDate
expected_priceFloat
selling_priceFloat
bedroomsInteger
living_areaInteger
facadesInteger
garageBoolean
gardenBoolean
garden_areaInteger
garden_orientationSelection

花园朝向有四个可选的值:‘North’, ‘South’, ‘East’ and ‘West’. 这里有个例子,注意元组中的两个值必须都是字符串。

lead_type = fields.Selection(
        string='Type',
        selection=[('lead', 'Lead'), ('opportunity', 'Opportunity')],
        help="Type is used to separate Leads and Opportunities")

修改完后重启odoo服务,别忘了-u选项

连接到psql并且检查estate_property表结构,你会发现多了一些额外的字段也被添加进了表中,我们将在后面介绍他们。

通用属性

目标: 在这一章节的末尾,name和expected_price 将被设置成不能为null

rd-demo=# \d estate_property;
                                            Table "public.estate_property"
    Column       |            Type             | Collation | Nullable |                   Default
--------------------+-----------------------------+-----------+----------+---------------------------------------------
...
name               | character varying           |           | not null |
...
expected_price     | double precision            |           | not null |
...

就像模型本身,字段可用通过属性来配置。

name = fields.Char(required=True)

一些属性在所有的字段类型中是通用的,这里是最常用的:

  • string (str, default: field’s name)

    UI中的字段标签.

  • required (bool, default: False)

    如果为真,该字段不能为空,它必须有一个默认值或者当创建一条记录的时候永远给一个值。

  • help (str, default: '')

    在UI中提供一个长格式的帮助说明

  • index (bool, default: False)

    请求Odoo为该字段生成索引

练习

FieldAttribute
namerequired
expected_pricerequired

重启服务后,就能看到效果。

Automatic Fields

参考: 关注这个主题的文档在这里 Automatic fields.

你应该注意到了,你的模型多了几个没定义的字段。odoo在所有的模型中都会创建几个字段,这些字段被系统管理并且不能被修改,但是如果需要的话可以读取。

  • id (Id)

    模型中一条记录的唯一标识。

  • create_date (Datetime)

    记录的创建时间

  • create_uid (Many2one)

    记录的创建者

  • write_date (Datetime)

    最近一次修改记录的时间

  • write_uid (Many2one)

    最后一次修改记录人

现在我们创建了我们的第一个模型,让我们增加一些安全机制。

直接写sql查询是可行的,不过这将绕过Odoo的身份认真和安全机制。

作业

在模块目录中新建model目录:

在模块的init 文件中 引入

from . import model

在model下建立init文件

同时引入

from . import estate_property

这样,数据就关联起来了。

estate_property.py

from odoo import models,fields

class EstateProperty(models.Model):
    """

    """
    _name = "estate.property"
    _description = "房屋信息数据"

    name = fields.Char(string="名称",required=True)
    description = fields.Text(string="描述")
    postcode = fields.Char(string="邮编")
    date_availability = fields.Date(string="到期时间")
    expected_price = fields.Float(string="期望价格",required=True)
    selling_price = fields.Float(string="销售价格")
    bedrooms = fields.Integer(string="房间数量")
    living_area = fields.Text(string="居住面积")
    facades = fields.Integer(string="朝向")
    garage = fields.Boolean(string="是否带车库")
    garden = fields.Text(string="是否带花园")
    garden_area = fields.Integer(string="花园面积")
    garden_orientation = fields.Selection(string="花园朝向",selection=("东","南","西","北"))


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值