精华内容
下载资源
问答
  • 当初个人学习时由于没有系统的教程走了不少弯路,现在官方文档相对齐全,但对没接触过odoo的人来说,很多地方不大习惯,所以本人根据官方文档,录制了一套基于odoo13的视频教程,本人也投入部分精力,象征性收取...

    Odoo功能强大,基础架构齐全,已经被多家企业应用,而且在国内使用的人越来越多,

       当初个人学习时由于没有系统的教程走了不少弯路,现在官方文档相对齐全,但对没接触过odoo的人来说,很多地方不大习惯,所以本人根据官方文档,录制了一套基于odoo13的视频教程,本人也投入部分精力,象征性收取费用,希望对大家有点帮助。

    视频链接:https://edu.csdn.net/course/detail/27841

    展开全文
  • ODOO13 开发教程一 认识odoo

    千次阅读 2019-11-08 10:14:29
    odoo是什么 我们要学习的odoo是什么? 首先,他是推荐基于Python语言做开发的Web框架,它和Django、Flask等Python前端框架一样。 odoo框架是开源的,它的长处在于快速搭建纯B/S架构的ERP系统,因为它是针对ERP的...

    odoo是什么

    我们要学习的odoo是什么?

    首先,他是推荐基于Python语言做开发的Web框架,它和Django、Flask等Python前端框架一样。

    odoo框架是开源的,它的长处在于快速搭建纯B/S架构的ERP系统,因为它是针对ERP的需求发展而来的,适合定制出符合客户各种需求的ERP系统和电子商务系统。在odoo框架中,odoo开发者已为我们预置了众多模块:销售、采购、库存、财务、生产、项目管理、CRM、POS、人力资源、车辆管理、午餐管理、网站等等。

    当然,他能做的并不只是ERP,作为odoo框架的使用者,我们完全可以构建出各种用途的B/S系统。这完全得益于odoo强大的底层结构,得益于odoo的最大特点——模块化。

    odoo的模块化 

    我们都知道积木、拼图、乐高等益智游戏的存在,这些游戏的完成品都是有一个又一个的部分组成的。

    我们使用odoo框架去开发系统就好像搭积木,拼拼图一样,作为框架使用者,我们要完成的系统就是乐高成品,而系统中的模块就是每一块乐高块。在我们要做的系统中,我门需要什么模块就开发安装什么模块,不需要就不安装,安装错了再卸载下来就可以了。系统要想变成什么样子,完全取决于你想要什么。所以上面说,odoo框架不是只能做ERP系统。

    odoo的优点

    与其罗列odoo的优点,不如说说它比传统框架有哪些优秀的地方。

    就拿ERP来说,传统ERP多为商用软件,相当封闭,对于不同用户是由一定的局限性的,用户购买后并不一定完全符合自身的需求,就会出现 我想要的没有,我不想要的显得冗余 或者 系统的某些地方不符合我实际需求的 情况。这就产生了一个系统改造及费用的问题。传统产品的升级加功能还好说,改功能可就麻烦了,因为这部分功能的改动,很有可能影响其他功能的使用。

    而odoo框架的模块特性、继承特性,很好的解决这一问题。odoo框架使用者只需要生产模块就行了,需要什么模块就开发什么模块。需要改造某部分功能,只需要改造某个模块后,升级模块就行了,odoo中的每一个模块都是可安装、可卸载、可升级的。这也就体现了它的超强定制性。

    odoo的缺点 

     同样,odoo也有不足之处,想要实现传统软件中的某些特别效果,由于受到odoo视图类型限制,开发起来并不方便。当然,odoo提供的QWEB前端开发,能够拯救这一点。但在挑剔且刻板的传统用户的需求面前,这似乎并不符合odoo快速开发的特点。

    扒一扒odoo的前生今生 

    展开全文
  • ODOO13 开发教程附 常用修饰器

    千次阅读 2020-01-02 18:11:17
    装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简短,也更Pythonic(Python范儿)。...在ODOO13 开发教程四 模型中的字段中,我们已经...

    装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简短,也更Pythonic(Python范儿)。

    odoo版本的更新,在以往各版本中,舍弃过一些装饰器,也增加过新的装饰器,目的是为了让开发代码 短小精悍。这篇文章中,只说明 Odoo13中常用的装饰器。

    在 ODOO13 开发教程四 模型中的字段 中,我们已经接触到一个装饰器了,叫 @api.depends

    @api.depends

    这个修饰器指定 计算字段的依赖项。每个参数必须是一个字符串(必须是字段名),多个参数用逗号隔开。比如:

    class ZeroneShelf(models.Model):
        _name = "zerone.shelf"
        _description = "Zerone Shelf"
    
        name = fields.Char("书架名称")
        capacity = fields.Integer("书架容量")
        capacity_rate = fields.Float(string="图书放置比", compute="_compute_rate")
    
        book_ids = fields.One2many('zerone.book', 'shelf_id', string="图书")
    
        @api.depends('capacity', 'book_ids')
        def _compute_rate(self):
            for record in self:
                if not record.capacity:
                    record.capacity_rate = 0.0
                else:
                    record.capacity_rate = 100.0 * len(record.book_ids) / record.capacity

    当书架容量被改变,或者增加、删除图书记录时,会触发此函数,重新计算capacity_rate。 

    增加图书记录时触发
    修改书架容量时触发

     


    @api.onchange

    在字段出现的表单视图中,当某个指定字段被修改时,将调用该方法。每个参数必须是一个字符串(必须是字段名),多个参数用逗号隔开。

    @api.onchange("capacity", "book_ids")
    def _onchange_capacity(self):
        if self.capacity < 0:
            return {
                'warning': {
                    'title': "书架容量值不正确",
                    'message': "书架容量不能小于 0",
                    'type': 'notification'
                }
            }
        if self.capacity < len(self.book_ids):
            return {
                'warning': {
                    'title': "图书太多了",
                    'message': "图书数量超过了书架容量值",
                },
            }

    在本例中,当你在视图中,改变图书容量值为负数,或者通过改变图书容量、图书记录条数使得容量小于图书记录条数时,会给出相应的提示。在return的字典中,如果类型type设置为notification,则警告将在通知中显示。否则,它将作为默认显示在对话框中。

    return字典中不设置type

     

    return字典中设置type

    注意:

    一、return 字典不是必须的,但你可以使用return字典,给用户提示。但是虽然有提示,提示并不会阻止用户的行为。也就是说,当用户将书架容量改为负数时,即使提醒了用户书架容量不能为负数,但书架容量值并不会因提示而跳回修改前的值。

    二、onchange 仅支持简单的字段名,像 shelf_id.name 这种带有关系的字段,会被忽略。 “ one2many”或“ many2many”字段无法通过onchange进行自我修改。

    三、onchange''返回伪记录的记录集,因此在上述记录集上调用任何一种CRUD方法都是未定义的行为,因为它们可能尚未存在于数据库中。

    在onchange的返回值中,除了title、message、type,还可以使用一个键:domain。一般使用domain时的场景是:当用户在视图中改变某个字段时,对其他字段进行筛选过滤。拿odoo源码举例,在设置公司信息时,改变选择的国家,国家下的省(州)会进行过滤,只筛选出属于当前选择的国家的省(州)。先看源码:

        def on_change_country(self, country_id):
            # This function is called from account/models/chart_template.py, hence decorated with `multi`.
            self.ensure_one()
            currency_id = self._get_user_currency()
            if country_id:
                currency_id = self.env['res.country'].browse(country_id).currency_id
            return {'value': {'currency_id': currency_id.id}}
    
    
        @api.onchange('country_id')
        def _onchange_country_id_wrapper(self):
            res = {'domain': {'state_id': []}}
            if self.country_id:
                res['domain']['state_id'] = [('country_id', '=', self.country_id.id)]
            values = self.on_change_country(self.country_id.id)['value']
            for fname, value in values.items():
                setattr(self, fname, value)
            return res


    @api.constrains

    上面的提到了onchange装饰器,可以给出提示,但不能阻止用户的行为。如果要程序既要给用户发出提示,还要阻止用户修改,你可以考虑使用constrains装饰器。constrains装饰器,又叫约束检查装饰器。参数也必须是字段,并以字符串的形式传入。举例|:在zerone_book.py 中为code字段增加约束检查装饰器:

    class ZeroneBook(models.Model):
        _name = "zerone.book"
        _description = "Zerone Books"
        
        ... ...
        
        @api.constrains('code')
        def _check_description(self):
            if self.search_count([('code', '=', self.code)]) > 1:
                raise ValidationError("图书编号必须是唯一的!")

    对于约束检查装饰器,在py文件中,还有一种叫_sql_constrains写法,可以达到一样的效果:

    class ZeroneBook(models.Model):
        _name = "zerone.book"
        _description = "Zerone Books"
        
        ... ...
    
        _sql_constraints = [
            ('book_code_uniq', 'unique (code)', '图书编号必须唯一!')
        ]

     _sql_constrains 是一个列表,里面可以写多个约束。约束格式为三元素的元组(唯一的约束名,约束方法、约束触发提示)。第二个参数为SQL约束方法,下面是几个常见的SQL约束:

    # 条件约束
    _sql_constraints = [
        ('check_name', "CHECK( (type='contact' AND name IS NOT NULL) or (type!='contact') )", 'Contacts require a name'),
    ]
    
    # 唯一约束
    _sql_constraints = [
        ('name_uniq', 'unique(name)', 'The name of the language must be unique !'),
        ('code_uniq', 'unique(code)', 'The code of the language must be unique !'),
        ('url_code_uniq', 'unique(url_code)', 'The URL code of the language must be unique !'),
    ]
    
    # 外键约束
    _sql_constraints = [
        ('lang_fkey_res_lang', 'FOREIGN KEY(lang) REFERENCES res_lang(code)', 'Language code of translation item must be among known languages'),
    ]

    注意:

    一、constrains装饰器,仅支持简单的字段名,像 shelf_id.name 这种带有关系的字段名,会被忽略。

    二、仅当装饰方法中的声明字段,包含在create或write调用中时,才会触发@constrains。


    @api.model 

     当方法中的self是一个记录集(包括一条记录),且方法只与模型有关,与任何记录集数据无关时,使用这个装饰器,此时的self代表的则是模型本身,和哪条数据记录无关。可以理解成类级别的静态方法。

    本教程只说大白话,能理解的大白话:使用这个装饰器,会给被装饰的方法,自动且自觉地带上模型该有的信息,而开发者不必再传参数。其实是对代码的优化,pythonic,注意,这时的self 只代表模型本身,与记录无关。

    在之前如果这么写的话:

    def method(self,cr,uid,context=None):  
        pass  
    

    在使用@api.model后,完全不必再传固定的参数 :

    @api.model  
    def method(self):  
        pass 
    

     从之前的书写方式来看的话,可以看到,是没有ids参数传入的。


    @api. model_create_multi

    此装饰器装饰一个使用字典列表并创建多个记录的方法,只修饰create方法。 可以使用单个字典或字典列表调用该方法。

        @api.model_create_multi
        def create(self, vals_list):
            users = super(Users, self).create(vals_list)
            for user in users:
                user.partner_id.write({'company_id': user.company_id.id, 'active': user.active})
            return users

    下面这些似乎并不常用, 有兴趣的可在阅读源码后,尝试写一个例子分享出来。

    @api.depends_context

    这个装饰器,可以与@api.depends放在一起讲,也可以与compute属性放在一起讲,考虑到我们的使用频率,我把他单独放到后面了。

    说可以与@api.depends放在一起讲,是因为它同 @depends 相似,不同的是@depends 依赖的是字段,@depends_context 依赖的是上下文。说可以与compute属性放在一起讲,是因为它需要和compute属性配合使用,而且compute属性修饰的字段必须是 store = False。看个例子吧:

    price = fields.Float(compute='_compute_product_price')
    
    @api.depends_context('pricelist')
    def _compute_product_price(self):
        for product in self:
            if product.env.context.get('pricelist'):
                pricelist = self.env['product.pricelist'].browse(product.env.context['pricelist'])
            else:
                pricelist = self.env['product.pricelist'].get_default_pricelist()
            product.price = pricelist.get_products_price(product).get(product.id, 0.0)

    @api.returns 

    用于返回model实例记录集。它接收的第一个参数为模型名,如果是当前模型,可以直接传 self 。它接收的第二个参数是一个方法,用来将记录形式的值转化成传统格式输出。它接收的第三个参数也是一个方法,用来将传统格式的值转化为记录形式输出。其中第一个参数是必须的,其他两个参数选择其中的一个。下面摘抄自Odoo源码,看不明白不要紧,这个装饰器似乎并不常用。具体使用方法,参考一下源码:

        # 返回当前模型记录集,传self即可
        @api.returns('self', lambda value: value.id)
        def copy(self, default=None):
            default = dict(default or {},
                           name=_("%s (copy)") % self.name)
            return super(SMSTemplate, self).copy(default=default)
    
    
        # 返回其他模型记录集,传递模型名
        @api.returns('mail.message', lambda value: value.id)
        def message_post(self, **kwargs):
            return super(HrEmployeePrivate, self._post_author()).message_post(**kwargs)
    
    
        # 第一参数为必须
        @api.returns('self')
        def _filter_visible_menus(self):
            """ Filter `self` to only keep the menu items that should be visible in
                the menu hierarchy of the current user.
                Uses a cache for speeding up the computation.
            """
            visible_ids = self._visible_menu_ids(request.session.debug if request else False)
            return self.filtered(lambda menu: menu.id in visible_ids)

     更多修饰器,请整理后在评论区分享。谢谢

     

     

    展开全文
  • odoo 开发教程

    2019-03-01 09:13:41
    odoo8原版开发教程,从入门到精通,英语原版 Odoo Development Essentials Credits About the Author About the Reviewers www.PacktPub.com Support files, eBooks, discount offers, and more Why subscribe? Free...
  • odoo 13安装教程

    千次阅读 2020-03-12 14:22:46
    配置数据库,包括的项目 db_user 和 db_password 是pgadmin4添加的用户 addons_path 就是项目的路径 ③pgadmin4添加用户 db_user db_passwoed 权限 ④配置pycharm 把setup文件夹下的odoo文件拷贝到外面,改名start。...

    ①获取压缩包

    链接: link.

    解压:
    在这里插入图片描述

    ②用pycharm打开

    添加一个conf文件。这个文件是用来配置的。配置数据库,包括的项目
    在这里插入图片描述
    db_user 和 db_password 是pgadmin4添加的用户
    addons_path 就是项目的路径

    ③pgadmin4添加用户

    在这里插入图片描述

    db_user

    在这里插入图片描述

    db_passwoed

    在这里插入图片描述

    权限

    在这里插入图片描述

    ④配置pycharm

    把setup文件夹下的odoo文件拷贝到外面,改名start。以后每次启动odoo就是启动这个文件
    在这里插入图片描述
    edit configgurations编辑一下运行的配置(不懂这步的小伙伴,可以直接右键上面的start.py文件,run,你的右上角就会出现
    在这里插入图片描述
    在这里插入图片描述

    ⑤pip依赖

    在这里插入图片描述
    把这个文件里面的依赖都要pip 哦
    为了方便我是把文件放在c盘下面直接pip的
    加上清华大学的镜像就会快很多
    在这里插入图片描述

    ⑥下载node js

    直接百度下载(讲道理我不太清楚这个是干嘛的,我们前辈教我的,我记录一下而已,哈哈哈
    在这里插入图片描述
    在这里插入图片描述

    ⑦最后run start.py

    在这里插入图片描述
    这样就成功了,打开浏览器访问:127.0.0.1:8069

    展开全文
  • Odoo13开发教程-搭建网站

    千次阅读 2019-12-11 22:59:26
    博主在外企IT领域工作多年,有一定的Python和ERP基础,最近偶然机会接触到开源ERP odoo,萌生了学习的念头,但是官网的开发教程都是英文,所以打算用浅显易懂的文字翻译成中文,方便大家一起学习,有翻译不到位的...
  • ODOO13 开发教程六 继承

    千次阅读 2020-01-11 11:49:32
    在这篇文章中,我们要学习odoo中的继承。如果你是一个新手,看到这里的时候,不要觉得继承是个高大上的东西,也不要去想这里的继承和之前学的Java/Python这些里的继承有什么不同,有什么相同的。你只需要知道,我们...
  • ODOO13 接口请求
  • 本文的推荐开发环境搭建使用 PyCharm、Python3.7、odoo13社区版 Windows系统下环境搭建 系统:Windows10 64位 开发工具:PyCharm 推荐使用专业版 Python版本: 3.7 odoo版本:13社区版 安装开发工具PyCharm ...
  • 本篇实际上为新的odoo开发者说明,如何在odoo中,使用第三方包将数据导出到Excel。事实上,odoo已经提供了数据的Excel导入和导出数据到Excel功能。也许你要问了,既然odoo已经提供了数据的导入导出,那为什么我们...
  • ODOO13 开发教程五 模块中的基本视图(常用视图)中介绍了常用的基本视图表单视图(form)和列表视图(tree)。在这篇文章中,将对Odoo中的高级视图做简单介绍。 Odoo的高级视图有 看板视图(kanban),日历视图 ...
  • 源码安装 Odoo 为便于管理,我们将在家目录下创建一个/odoo-dev 目录作为工作目录。在本系列文章中我们均假设 Odoo 安装在/odoo-dev 目录下。 Odoo 使用的是 Python 3(3.5 或之后的版本),那么在命令行中我们将...
  • ODOO13 开发教程五 模块中的基本视图(常用视图)

    千次阅读 热门讨论 2020-01-03 15:25:25
    在这篇文章中,我会根据上一篇文章中写的代码,整理出Odoo中的基本视图的基本使用方法,并可能向高级视图进行拓展。 Odoo中的视图层,定义了模型记录的显示方式。在Odoo中有多种视图,如最基本的视图就有 form、...
  • ODOO13 开发教程附 模块目录结构

    千次阅读 2019-12-25 10:09:20
    业务对象被声明为Python类,写在.py文件中(称为资源文件),这些资源文件由Odoo根据在__init__.py文件中的引用配置生效。注:瞬态模型文件,通常存放在wizard文件夹下。往下看。 对象视图层 对象视图层,在模块目录...
  • Odoo视频教程,根据Odoo官方文档,从0搭建一个开放学院的模块,内容涵盖了odoo的orm、视图view、安全设置、国际化、远程调用等方面,是odoo官方的推荐入门路线。经测试,本课程适用于 odoo13 odoo14版本
  • 清单文件用于将python软件包声明为Odoo模块,并指定模块元数据。 它是一个名为 __manifest__.py的文件,包含了一个Python字典,其中每个键都指定模块元数据。 { 'name': "A Module", 'version': '1.0', '...
  • ODOO13 开发教程七 自动编号的使用

    千次阅读 2020-02-13 14:48:48
    创建 data/ir_sequence_data.xml 并在__manifest__.py文件中引用 <?xml version="1.0" encoding="utf-8"?...odoo> <data noupdate="1"> <record id="seq_sps_order" model="ir.sequence"&...
  • ODOO13 开发教程四 模型中的字段

    千次阅读 2019-12-29 12:50:28
    在这篇文章中,我将整理出odoo中不同类型的字段及其它们的使用。在开始之前,我必须再给大家讲讲蛋挞王子的故事。 在上节中,小程序猿为蛋挞王子做了一个图书管理的模块,并进行了安装测试。但很明显,模块太简单了...
  • ODOO13 开发教程三 开始你的第一个模块

    千次阅读 多人点赞 2019-11-20 17:17:59
    ”继母说:“我要《手摸手odoo开发教程》,你能找到吗?”话音刚落,继母拿着指甲钳向蛋挞王子扑来。 蛋挞王子一个激灵惊醒,嚎啕大哭。小程序猿们被吵醒了,问他怎么了。蛋挞王子向他们说了自己做的梦后,小程序猿...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 173
精华内容 69
关键字:

odoo13教程