在 odoo 15 中从向导创建报告

Create report from wizard in odoo 15

我想从向导创建报告 pdf,但它不起作用,这是我的代码:

/var/www/html/odoo_15/addons/school/wizard/search_and_print_calendar_wizard_view.xml

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <record id="view_school_search_and_print_calendar_wizard" model="ir.ui.view">
        <field name="name">Search and Print Calendar</field>
        <field name="model">school.search.and.print.calendar.wizard</field>
        <field name="arch" type="xml">
            <form string="Search and Print Calendar">
                <sheet>
                    <group>
                        <field name="student_id"/>
                        <field name="date_from"/>
                        <field name="date_to"/>
                    </group>
                </sheet>
                <footer>
<!--                    <button name="school_view_calendars" string="View Calendars" type="object" class="btn-primary"/>-->
                    <button name="school_print_calendars" string="Print Calendars" type="object" class="btn-primary"/>
                    <button string="Cancel" class="btn-secondary" special="cancel" data-hotkey="z" />
                </footer>
            </form>
        </field>
    </record>

    <record id="action_school_search_and_print_calendar" model="ir.actions.act_window">
        <field name="name">School Search and Print Calendar</field>
        <field name="res_model">school.search.and.print.calendar.wizard</field>
        <field name="view_mode">form</field>
        <field name="target">new</field>
    </record>
</odoo>

/var/www/html/odoo_15/addons/school/wizard/search_and_print_calendar_wizard.py

from odoo import api, models, fields, _

class SearchAndPrintCalendarWizard(models.TransientModel):
    _name = "school.search.and.print.calendar.wizard"
    _description = "Search and Print Calendar Wizard"

    student_id = fields.Many2one('school.students', string='Student', required=True)
    date_from = fields.Datetime(string='Date From')
    date_to = fields.Datetime(string='Date To')

    # view list calendars based on student id
    # def school_view_calendars(self):
    #     print('aaa')

    def school_print_calendars(self):
        data = {
            'form': self.read()[0]
        }
        report_action = self.env.ref('school.action_report_calendar').report_action(self, data=data)

        return report_action

/var/www/html/odoo_15/addons/school/report/calendar_report.xml

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <!-- pdf version -->
        <record id="action_report_calendar" model="ir.actions.report">
            <!-- this field will show as name of the button,
            also will be the name of exported file, unless we use print_report_name as below -->
            <field name="name">Calendar Report</field>
            <field name="model">school.search.and.print.calendar.wizard</field>
            <field name="report_type">qweb-pdf</field>
            <!-- In single report, this print_report_name will be use as dynamic name of the file.
            But in multiple reports, this will not work, it will use <field name="name"> as file name.
            So we should use print_report_name for single report, and <field name="name"> to multiple reports.
            -->
            <field name="print_report_name">'Calendar - [%s]' % (object.sequence).replace('/', '')</field>
            <!-- the view file is declare in this variable -->
            <field name="report_name">school.report_calendar</field>
            <!-- not sure what this for -->
            <field name="report_file">school.report_calendar</field>
            <!-- not sure what this for -->
            <field name="binding_model_id" ref="model_school_search_and_print_calendar_wizard"/>
            <field name="binding_type">report</field>
        </record>
    </data>
</odoo>

/var/www/html/odoo_15/addons/school/report/calendar_report_template.xml

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <!-- this template id is called in report/calendar_report.xml -->
    <template id="report_calendar">
        <t t-call="web.html_container">
            <!-- docs is the record data -->
            <!-- this command equal to foreach(docs as o) -->
            <t t-call="web.external_layout">
                <!-- html code -->
                <div class="page">
                    <div class="oe_structure"/>
                    <div>
                        <h2>This is a test</h2>
                    </div>
                </div>
            </t>
        </t>
    </template>
</odoo>

我遇到了这个问题:

AttributeError: 'NoneType' object has no attribute 'compile'
AttributeError: 'NoneType' object has no attribute 'CompileError'

全期:

Traceback (most recent call last):
  File "/var/www/html/odoo-server/odoo/odoo/api.py", line 886, in get
    return field_cache[record._ids[0]]
KeyError: <NewId 0x7f3bbbc7b7f0>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/var/www/html/odoo-server/odoo/odoo/fields.py", line 1057, in __get__
    value = env.cache.get(record, self)
  File "/var/www/html/odoo-server/odoo/odoo/api.py", line 889, in get
    raise CacheMiss(record, field)
odoo.exceptions.CacheMiss: 'base.document.layout(<NewId 0x7f3bbbc7b7f0>,).preview'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/var/www/html/odoo-server/odoo/addons/web/models/base_document_layout.py", line 290, in _compile_scss
    return libsass.compile(
AttributeError: 'NoneType' object has no attribute 'compile'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/var/www/html/odoo-server/odoo/odoo/addons/base/models/ir_http.py", line 237, in _dispatch
    result = request.dispatch()
  File "/var/www/html/odoo-server/odoo/odoo/http.py", line 688, in dispatch
    result = self._call_function(**self.params)
  File "/var/www/html/odoo-server/odoo/odoo/http.py", line 360, in _call_function
    return checked_call(self.db, *args, **kwargs)
  File "/var/www/html/odoo-server/odoo/odoo/service/model.py", line 94, in wrapper
    return f(dbname, *args, **kwargs)
  File "/var/www/html/odoo-server/odoo/odoo/http.py", line 349, in checked_call
    result = self.endpoint(*a, **kw)
  File "/var/www/html/odoo-server/odoo/odoo/http.py", line 917, in __call__
    return self.method(*args, **kw)
  File "/var/www/html/odoo-server/odoo/odoo/http.py", line 536, in response_wrap
    response = f(*args, **kw)
  File "/var/www/html/odoo-server/odoo/addons/web/controllers/main.py", line 1335, in call_kw
    return self._call_kw(model, method, args, kwargs)
  File "/var/www/html/odoo-server/odoo/addons/web/controllers/main.py", line 1327, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "/var/www/html/odoo-server/odoo/odoo/api.py", line 464, in call_kw
    result = _call_kw_multi(method, model, args, kwargs)
  File "/var/www/html/odoo-server/odoo/odoo/api.py", line 451, in _call_kw_multi
    result = method(recs, *args, **kwargs)
  File "/var/www/html/odoo-server/odoo/odoo/models.py", line 6475, in onchange
    snapshot1 = Snapshot(record, nametree)
  File "/var/www/html/odoo-server/odoo/odoo/models.py", line 6257, in __init__
    self.fetch(name)
  File "/var/www/html/odoo-server/odoo/odoo/models.py", line 6267, in fetch
    self[name] = record[name]
  File "/var/www/html/odoo-server/odoo/odoo/models.py", line 5874, in __getitem__
    return self._fields[key].__get__(self, type(self))
  File "/var/www/html/odoo-server/odoo/odoo/fields.py", line 1106, in __get__
    self.compute_value(recs)
  File "/var/www/html/odoo-server/odoo/odoo/fields.py", line 1265, in compute_value
    records._compute_field_value(self)
  File "/var/www/html/odoo-server/odoo/odoo/models.py", line 4256, in _compute_field_value
    getattr(self, field.compute)()
  File "/var/www/html/odoo-server/odoo/addons/web/models/base_document_layout.py", line 121, in _compute_preview
    preview_css = markupsafe.Markup(self._get_css_for_preview(styles, wizard_with_logo.id))
  File "/var/www/html/odoo-server/odoo/addons/web/models/base_document_layout.py", line 270, in _get_css_for_preview
    css_code = self._compile_scss(scss)
  File "/var/www/html/odoo-server/odoo/addons/web/models/base_document_layout.py", line 298, in _compile_scss
    except libsass.CompileError as e:
Exception

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/var/www/html/odoo-server/odoo/odoo/http.py", line 644, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "/var/www/html/odoo-server/odoo/odoo/http.py", line 302, in _handle_exception
    raise exception.with_traceback(None) from new_cause
AttributeError: 'NoneType' object has no attribute 'CompileError'

我正在关注 Odoo 伙伴 Odoo-14 教程。

这是我的 github 代码: https://github.com/saxsax1995/odoo-15-school

请帮忙,谢谢。

请领导帮忙解决,调试后发现是缺少库"sass","libsass"

解决问题的方法如下:

sudo apt-get install python3.8-dev
pip install --upgrade setuptools
pip install sass
pip install libsass