Odoo8 custom view module

绝地灬酷狼 2022-08-10 05:49 138阅读 0赞

http://www.codeproject.com/Tips/998870/Odoo-custom-view-module

Introduction

The tip covers 2 separate Odoo8 modules

  1. The view module: creates a simple view that prints sample buttons and a given QWeb template content provided by the other module.
  2. The demo module: provides an example and a sample QWeb template to use the view module.

The code can be used as a base to create any custom view type for Odoo8.

custom-odoo8-view-sc.png

Background

While implementing Odoo8 for a “training center” we needed a page that an instructor can use to check his schedule, that page would need to appear as a calendar and clearly show start and end time of a given course over an interval, the way we needed to display it is pretty different from the built in calendar so we had to find a way to create a custom calendar view and use it in our module.

The View Module

The module is called web_dummy, the name doesn’t matter but we have to note it as it needs to appear in a few places in the code, our module will have the following files:

/static/src/css/dummy.css

For custom view’s related css, empty in our case since we won’t have a custom look and is just included for completeness.

/static/src//js/dummy.js

For the custom view’s logic and actions, in that file we need to create a javascript “class” and initialize it, the example js here was copied from the kanban view, renamed and stripped down and modified as needed for the example.

Our class is instance.web_dummy.DummyView, we need to note that web_dummy has to match the module name web_dummy else this’ll result in errors along the lines of “unable to find class”.

Hide Copy Code

  1. <span style="line-height: normal;">instance.web_dummy.DummyView = instance.web.View.extend({….});
  2. </span>

we also need to add it as a web view like that

Hide Copy Code

  1. instance.web.views.add('dummyview', 'instance.web_dummy.DummyView');

init function is the entry point, typically needs to initialize class variables.

Hide Copy Code

  1. init: function (parent, dataset, view_id, options) {
  2. this._super(parent, dataset, view_id, options);
  3. var self = this;
  4. this.fields_view = {};
  5. this.fields_keys = [];
  6. this.qweb = new QWeb2.Engine();
  7. this.qweb.debug = instance.session.debug;
  8. this.qweb.default_dict = _.clone(QWeb.default_dict);
  9. this.has_been_loaded = $.Deferred();
  10. this.currently_dragging = {};
  11. this.limit = options.limit || 40;
  12. this.add_group_mutex = new $.Mutex();
  13. },

view_loading function receives a single variable that has the xml view of the calling view (ex: the view from the other module using that view) and should process that variable to load data and bind parameters….etc.

Hide Shrink arrow-up-16.png Copy Code

  1. view_loading: function(r) {
  2. return this.load_dummyview(r);
  3. },
  4. load_dummyview: function(data) {
  5. this.fields_view = data;
  6. // use default order if defined in xml description
  7. var default_order = this.fields_view.arch.attrs.default_order,
  8. unsorted = !this.dataset._sort.length;
  9. if (unsorted && default_order) {
  10. this.dataset.set_sort(default_order.split(','));
  11. }
  12. this.$el.addClass(this.fields_view.arch.attrs['class']);
  13. this.$buttons = $(QWeb.render("DummyView.buttons", {
  14. 'widget': this}));
  15. this.$cont = data.arch.children;
  16. if (this.options.$buttons) {
  17. this.$buttons.appendTo(this.options.$buttons);
  18. } else {
  19. this.$el.find('.oe_dummyview_buttons').replaceWith(this.$buttons);
  20. }
  21. this.$el.find('.oe_dummyview_content').append(this.$cont);
  22. this.$groups = this.$el.find('.oe_dummyview_groups tr');
  23. this.fields_keys = _.keys(this.fields_view.fields);
  24. this.add_qweb_template();
  25. this.$cont=this.qweb.render('dummy-content', this.qweb_context);
  26. this.$el.find('.oe_dummyview_content').replaceWith(this.$cont);
  27. this.has_been_loaded.resolve();
  28. this.trigger('dummyview_view_loaded', data);
  29. return $.when();
  30. },

add_qweb_template and transform_qweb_template are used to process QWeb templates from the calling module in order to allow loading them inside the custom view’s template, this is something specific to the kanban view and this module since both allow loading a qweb template inside the view they provide and may or may not be needed for a custom view…this really depends on the reason to create the view and its specs.

/static/src/xml/web_dummy.xml

Templates the js file can use

In that file we have 2 templates defined, one for the main body (called “DummyView”) and the other for the buttons (called “DummyView.buttons”), names here need to match the names used in the js file, also css classes are important and some of them are used by the js file to place content/buttons…etc

/views/web_dummy.xml

The main layout file, typically used to include the view’s js and css files

/__init__.py

Python module entry point, typically used to include other py files for the classes

/__openerp__.py

Odoo module entry point, typically used to define the other modules this module requires to function properly, it also defines the display name, version, category and description of the module alongside with the xml files that need to be included.

/models.py

The actual file that contains our custom python classes.

The tricky part here is that when activating/updating a new module Odoo validates its xml and tries to make sure the view types and fields are valid, that’s good but the part with validating the view type requires some work as it compares the name against a static drop down type field called “type” in a class named “ir.ui.view” so we need to append our new type to the list here without modifying the core files, so we’ll create a new class called view -or anything that’s unique and meaningful to the module- and have it inherit “ir.ui.view” then we need to override its __init__ function to initialize its parent class and add our type as needed like the following

Hide Copy Code

  1. def __init__(self, pool, cr):
  2. super(view, self).__init__(pool, cr)
  3. super(view, self)._columns['type'].selection.append(('dummyview','DummyView'))

The Demo Module

This is a simple Odoo8 module that’s used to demonstrate the functionality of the custom view.

That module is called demo_dummy and has the following structure:

/__init__.py

The python module entry point, includes “/models.py”

/__openerp__.py

The main Odoo entry point, defines the module’s name, description, category, author and version, also defines the modules this one relies on to function (ex: web_dummy) and the data/template files to include.

/models.py

This file contains the classes(models) that define the data and logic the module relies on to function.

For this example we’ll be using a single class called dummy, with name “demo_dummy.content” that doesn’t have any fields.

Hide Copy Code

  1. class dummy(models.Model):
  2. _name = 'demo_dummy.content'
  3. _description = 'Dummy content'

/templates.xml

This file defines the menu structures and the view layouts for that module, access needed for each menu item if any (not related to the demonstration)

we’ll define a main level menu item called Dummy Example

Hide Copy Code

  1. <menuitem name="Dummy Example" id="demo_dummy.content" />

then we’ll define a section menu item called Demo

Hide Copy Code

  1. <menuitem name="Demo" id="demo_dummy.content1" parent="demo_dummy.content"/>

and the most important part here is the following code

Hide Shrink arrow-up-16.png Copy Code

  1. <record model="ir.ui.view" id="demo_dummy">
  2. <field name="name">demo.dummy</field>
  3. <field name="model">demo_dummy.content</field>
  4. <field name="arch" type="xml">
  5. <dummyview>
  6. <templates>
  7. <t t-name="dummy-content">
  8. <div class="col-md-12">
  9. <h2>Lorem ipsum</h2>
  10. <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin id lorem fringilla, aliquet orci ac, hendrerit ex. Nullam purus turpis, aliquet nec facilisis at, vehicula non lorem. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Maecenas tincidunt ex metus, ultricies ullamcorper velit molestie eget. In hac habitasse platea dictumst. Aenean rutrum rhoncus turpis sit amet tincidunt. Mauris commodo justo quis quam ultricies, nec blandit nulla interdum. Sed vulputate lacus erat, in auctor ipsum malesuada at. In vehicula velit enim, quis sollicitudin nunc facilisis non. Praesent a metus hendrerit, rutrum turpis sed, commodo justo. Nulla suscipit risus vel felis consectetur consectetur. Morbi mi nunc, tempor sit amet quam id, posuere molestie metus.</p>
  11. <p>In accumsan blandit libero. Aliquam pharetra convallis enim, quis pretium lacus scelerisque ut. Nunc et velit nec ligula pretium molestie. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam in leo eget ante egestas condimentum. Donec lobortis, est non commodo consequat, arcu purus posuere erat, id faucibus sapien arcu quis lectus. Quisque commodo ut arcu ultrices posuere. Phasellus interdum justo non tellus egestas sodales. Mauris bibendum sapien a sem maximus rhoncus. Nulla molestie urna sem, sit amet feugiat est sodales ut. Aliquam eu efficitur sapien. Duis libero libero, elementum et sem lacinia, rhoncus elementum erat. Maecenas euismod tortor et fermentum condimentum. Quisque non efficitur justo. </p>
  12. </div>
  13. </t>
  14. </templates>
  15. </dummyview>
  16. </field>
  17. </record>

here we’ve defined a view with architecture dummyview (like kanbanview and calendar) with an inner template named “dummy-content” that can contain pretty much any html code, that code will be placed by the logic of the view type as the body of the page

then we define a 3rd level menu item called Content that links to the action

Hide Copy Code

  1. <menuitem name="Content" id="demo_dummy.content2" action="demo_dummy_cont" parent="demo_dummy.content1"/>

Points of Interest

  • Odoo8 relies heavily on javascript, Qweb engine and bootstrap 3.
  • Typically I’d pick an existing view that’s pretty close to what I want to create and start modifying it.
  • The “proper” way to modify a model’s static dropdown field’s options is to inherit then initialize the parent then modify the parent’s variable.
  • The way to do that is pretty much undocumented, might not be intended or planned to by the developers of the software.

History

The attached code is also publicly avaiable at https://gitlab.com/groups/odoo-dummy-view, can be forked or modified as needed.

发表评论

表情:
评论列表 (有 0 条评论,138人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Odoo8.0中使用多进程

    因为用户业务量增加,在使用Odoo时开始有出现性能问题,暂时还没有进行其它方面的性能诊断和调优,先了解一下odoo的处理机制,根据网上的说明,odoo有一个workers的参数