4.odoo入门——培训签到课程项目(一)

来源:互联网 发布:java sleep使用 编辑:程序博客网 时间:2024/06/05 19:50

简书中文教程:http://www.jianshu.com/u/d4607d4b7c50

英文官方文档:http://www.odoo.com/documentation/10.0/

镜像网站:http://odoo-10-dev-translation.readthedocs.io/zh_CN/latest/howtos/backend.html

我们的任务是必须在odoo上开发出一个简单的培训签到记录表

首先要看懂在odoo上一个项目的结构:

在odoo10上,wens_app(我们自己创建的项目文件)下有若干个文件夹,其中每一个文件夹都对应着一个应用,我们可以打开odoo服务端(localhost:3069)中安装对应的的应用,这次我们创建的项目文件为ws_training,一般会包含几个文件夹:controllers, models, report, static, templates, views, 其下有2个文件__init__.py和__manifest__.py,__init__.py中包含入了当前文件中的所有目录,例如ws_training下的__init__.py代码如下:

import modelsimport reportimport controllersimport os

那models/trainning.py文件如下:

import loggingfrom odoo import models, fields, apiclass ws_training_attend(models.Model):#继承models.Model,定义对象模型,生成签到数据表    ''' 在模块安装完成后,odoo的ORM框架会自动把这个对象映射到数据库表。        属性类型会映射到表字段数据类型,表名是_name这个成员字符串(逗号变成下划线) '''    _name = 'ws.training.attend'    _description = u'培训签到表' #这不是继承的属性    user_id = fields.Many2one('res.users', string=u'学员', required=True) ##Many2one是一个框架中的类——在odoo/fileds.py中    course_id = fields.Many2one('ws.training.course', string=u'课程', required=True)    attend_time = fields.Datetime(string=u'签到时间', required=True, help=u'签到时间')    description = fields.Text(string=u'备注')    '''Datetime的定义如下:#可以查看odoo10/odoo/fields.py中的Datetime类的定义        class Datetime(Field):        type = 'datetime'        column_type = ('timestamp', 'timestamp')        @staticmethod        def now(*args):            """ Return the current day and time in the format expected by the ORM.                This function may be used to compute default values.            """            return datetime.now().strftime(DATETIME_FORMAT)        Datetime类也是继承于Field类的    '''    @api.model    def search(self, args, offset=0, limit=None, order=None, count=False):        context = self._context or {}        import time        time.sleep(1)        return super(ws_training_attend, self).search(args, offset, limit, order, count=count)    @api.multi    def write(self, vals):        context = self._context or {}        print vals        vals['description']='hello overwrote!'        return super(ws_training_attend, self).write(vals)    # @api.model    # def create(self, args, offset=0, limit=None, order=None, count=False):    #     context = self._context or {}    #     import time    #     time.sleep(15)    #     return super(ws_training_attend, self).search(args, offset, limit, order, count=count)    #    # @api.model    # def unlink(self, args, offset=0, limit=None, order=None, count=False):    #     context = self._context or {}    #     import time    #     time.sleep(15)    #     return super(ws_training_attend, self).search(args, offset, limit, order, count=count)class ws_training_course(models.Model): #生成课程数据表    _name = 'ws.training.course'  #数据库表的名字    _description = u'培训课程'    name = fields.Char(string=u'名称', required=True)    time_start = fields.Datetime(string=u'开始时间', required=True)    time_end = fields.Datetime(string=u'结束时间', required=True)    teacher_id = fields.Many2one('res.users', string=u'讲师', required=True)    description = fields.Text(string=u'描述')    #继承Model类,生成对应的数据表    #OpenERP 核心是一个完整的ORM对象关系映射层,开发人员不必编写基本的 SQL 语句。业务对象通过继承 osv.Model 类来渲染。    # ORM 的特点是使用预定义的属性指定一个业务对象。class res_users(models.Model):  #自己定义的用户资料数据库,密码是明文存储    _name = 'ws.training.users'    _description = u'描述'    user_name = fields.Char(string=u'用户名', required=True)    password = fields.Char(string=u'密码', required=True)    user_role = fields.Char(string=u'用户类型', required=True)

有一个类,继承的是models.Model,它是odoo10/odoo/models.py中的一个类:

Model类的定义如下:

AbstractModel = BaseModelclass Model(AbstractModel):    """ Main super-class for regular database-persisted Odoo models.    Odoo models are created by inheriting from this class::        class user(Model):            ...    The system will later instantiate the class once per database (on    which the class' module is installed).    """    _auto = True                # automatically create database backend    _register = False           # not visible in ORM registry, meant to be python-inherited only    _abstract = False           # not abstract    _transient = False          # not transient

Model类继承于AbstractModel(BaseModel):

其中BaseModel中有一些成员定义如下:

__metaclass__ = MetaModel_auto = False               # don't create any database backend_register = False           # not visible in ORM registry_abstract = True            # whether model is abstract_transient = False          # whether model is transient_name = None                # the model name_description = None         # the model's informal name_custom = False             # should be True for custom models only_inherit = None             # Python-inherited models ('model' or ['model'])_inherits = {}              # inherited models {'parent_model': 'm2o_field'}_constraints = []           # Python constraints (old API)_table = None               # SQL table name used by model_sequence = None            # SQL sequence to use for ID field_sql_constraints = []       # SQL constraints [(name, sql_def, message)]_rec_name = None            # field to use for labeling records_order = 'id'               # default order for searching results_parent_name = 'parent_id'  # the many2one field used as parent field_parent_store = False       # set to True to compute MPTT (parent_left, parent_right)_parent_order = False       # order to use for siblings in MPTT_date_name = 'date'         # field to use for default calendar view_fold_name = 'fold'         # field to determine folded groups in kanban views_needaction = False         # whether the model supports "need actions" (see mail)_translate = True           # False disables translations export for this model_depends = {}               # dependencies of models backed up by sql views                            # {model_name: field_names, ...}# default values for _transient_vacuum()_transient_check_count = 0_transient_max_count = lazy_classproperty(lambda _: config.get('osv_memory_count_limit'))_transient_max_hours = lazy_classproperty(lambda _: config.get('osv_memory_age_limit'))CONCURRENCY_CHECK_FIELD = '__last_update'

那么我们在trainning.py中写的类的定义就可以继承这些数据成员


注意到参考代码中有fileds中的Many2one函数,再去查看库函数:在odoo10/odoo/fields.py中有Many2one的类:

类的声明是:

classMany2one(_Relational): 说明继承于_Relational这个类

其构造函数如下:

def __init__(self, comodel_name=Default, string=Default, **kwargs):    super(Many2one, self).__init__(comodel_name=comodel_name, string=string, **kwargs)

再可以看到_Relational这个类的定义:

class _Relational(Field):    """ Abstract class for relational fields. """

它是继承于Field这个类的,Field类定义如下:

class Field(object):

其中有非常多的字段,截取其中可能用到的几条来说说:

:param string: the label of the field seen by users (string); if not    set, the ORM takes the field name in the class (capitalized).:param required: whether the value of the field is required (boolean, by    default ``False``)

那么比如:

course = fields.Many2one('res.course',string = "课程",required = True)

这样一条语句就会在数据库创建对应的表,生成一个列


原创粉丝点击