Your Name 2 månader sedan
förälder
incheckning
0aab6fe301

+ 8 - 0
cat_app/__manifest__.py

@@ -23,6 +23,7 @@
     'depends': ['base'],
 
     # always loaded
+    # 视图文件通常在权限文件之后
     'data': [
         # 'security/ir.model.access.csv',
         'views/views.xml',
@@ -30,7 +31,14 @@
         "security/library_security.xml",
         'security/ir.model.access.csv',
         'views/library_menu.xml',
+        'views/book_view.xml',
     ],
+    # 加载静态资源
+    # 'assets': {
+    #     'web.assets_backend': [
+    #         'css/custom_styles.css',
+    #     ],
+    # },
     # only loaded in demonstration mode
     'demo': [
         'demo/demo.xml',

+ 2 - 1
cat_app/controllers/__init__.py

@@ -1,3 +1,4 @@
 # -*- coding: utf-8 -*-
 
-from . import controllers
+from . import controllers
+from . import main

+ 8 - 0
cat_app/controllers/main.py

@@ -0,0 +1,8 @@
+from odoo import http
+class Books(http.Controller):
+    @http.route('/library/books', auth='user')
+    def list(self, **kwargs):
+        Book = http.request.env['library.book']
+        books = Book.search([])
+        return http.request.render(
+            'library_app.book_list_template', {'books':books})

+ 13 - 0
cat_app/css/styles.css

@@ -0,0 +1,13 @@
+.custom-button {
+    background-color: #4CAF50; /* 绿色背景 */
+    color: white; /* 白色文字 */
+    border: none; /* 无边框 */
+    padding: 10px 20px; /* 内边距 */
+    text-align: center; /* 文字居中 */
+    text-decoration: none; /* 无下划线 */
+    display: inline-block; /* 内联块元素 */
+    font-size: 16px; /* 字体大小 */
+    margin: 4px 2px; /* 外边距 */
+    cursor: pointer; /* 鼠标指针样式 */
+    border-radius: 8px; /* 圆角 */
+}

+ 25 - 2
cat_app/models/library_book.py

@@ -1,5 +1,5 @@
 from odoo import fields, models
-
+from odoo.exceptions import ValidationError
 
 """
 odoo会自动为模型添加一些特殊字段:
@@ -26,4 +26,27 @@ class Book(models.Model):
     image = fields.Binary('Cover')
     # Many2one表示一对多关系,Many2many表示多对多关系
     publisher_id = fields.Many2one('res.partner', string='Publisher')
-    author_ids = fields.Many2many('res.partner', string='Authors')
+    author_ids = fields.Many2many('res.partner', string='Authors')
+
+    def button_check_isbn(self):
+        """检查ISBN的有效性"""
+        # 遍历当前记录集中的每一条记录
+        for book in self:
+            if not book.isbn:
+                raise ValidationError('Please provide an ISBN for %s' % book.name)
+            if book.isbn and not book._check_isbn():
+                raise ValidationError('%s is an invalid ISBN' % book.isbn)
+        return True
+    
+    def _check_isbn(self):
+        """检查ISBN是否有效"""
+        # 确保当前记录集只有一条记录
+        self.ensure_one() 
+        isbn = self.isbn.replace('-', '') # 为保持兼容性自行添加
+        digits = [int(x) for x in isbn if x.isdigit()]
+        if len(digits) == 13:
+            ponderations = [1, 3] * 6
+            terms = [a * b for a,b in zip(digits[:12], ponderations)]
+            remain = sum(terms) % 10
+            check = 10 - remain if remain !=0 else 0
+            return digits[-1] == check

+ 60 - 9
cat_app/views/book_view.xml

@@ -1,19 +1,70 @@
 <odoo>
+    <!--ir.ui.view表示这是一个用户界面视图-->
+    <!--表单视图-->
     <record id="view_form_book" model="ir.ui.view">
         <field name="name">Book Form</field>
         <field name="model">library.book</field>
+        <!--定义视图的架构和类型-->
         <field name="arch" type="xml">
+            <!--form元素定义了表单视图的结构,表单标题为Book-->
             <form string="Book">
-                <group>
-                    <field name="name" />
-                    <field name="author_ids" widget="many2many_tags" />
-                    <field name="publisher_id" />
-                    <field name="date_published" />
-                    <field name="isbn" />
-                    <field name="active" />
-                    <field name="image" widget="image" />
-                </group>
+                <header>
+                    <!-- 此处添加按钮,type(object/action) -->
+                    <!--class:应用 CSS 样式的可选属性,与HTML中用法相同,需__manifest__.py中添加css文件路径
+                    'assets': {'web.assets_backend': ['path/css/styles.css',],},-->
+                    <!-- <button name="button_check_isbn" type="object" string="Check ISBN" class="custom-button" /> -->
+                    <button name="button_check_isbn" type="object" string="Check ISBN" />
+                </header>
+                <sheet>
+                    <!--group元素用于将字段分组,便于布局和组织-->
+                    <!--widget设置使用的部件-->
+                    <group name="group_top">
+                        <group name="group_left">
+                            <field name="name" />
+                            <field name="author_ids" widget="many2many_tags" />
+                            <field name="publisher_id" />
+                            <field name="date_published" />
+                        </group>
+                        <group name="group_right">
+                            <field name="isbn" />
+                            <field name="active" />
+                            <field name="image" widget="image" />
+                        </group>
+                    </group>
+                </sheet>
             </form>
         </field>
     </record>
+    <!--列表视图-->
+    <record id="view_tree_book" model="ir.ui.view">
+        <field name="name">Book List</field>
+        <field name="model">library.book</field>
+        <field name="arch" type="xml">
+            <!--tree定义树视图的根元素,表示这是一个以表格形式显示记录的视图-->
+            <tree>
+                <field name="name" />
+                <field name="author_ids" widget="many2many_tags" />
+                <field name="publisher_id" />
+                <field name="date_published" />
+            </tree>
+        </field>
+    </record>
+    <!--搜索视图-->
+    <record id="view_search_book" model="ir.ui.view">
+        <field name="name">Book Filters</field>
+        <field name="model">library.book</field>
+        <field name="arch" type="xml">
+            <!--search定义搜索视图的根元素,表示这是一个用于搜索和过滤记录的视图-->
+            <search>
+                <field name="publisher_id" />
+                <!--filter定义一个过滤器,domain定义筛选条件-->
+                <filter name="filter_active"
+                    string="Active"
+                    domain="[('active','=',True)]" />
+               <filter name="filter_inactive"
+                    string="Inactive"
+                    domain="[('active','=',False)]" />
+            </search>
+        </field>
+    </record>
 </odoo>