odoo_dev 开发培训作业:图书管理系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 line
3.5KB

  1. from odoo import api, fields, models
  2. from odoo.exceptions import Warning
  3. from odoo.exceptions import ValidationError
  4. class Book(models.Model):
  5. _name = 'library.book'
  6. _description = 'Book'
  7. _order = 'name, date_published desc'
  8. # 字符字段
  9. name = fields.Char('Title', required=True)
  10. isbn = fields.Char('ISBN')
  11. book_type = fields.Selection(
  12. [('paper', 'Paperback'),
  13. ('hard', 'Hardcover'),
  14. ('electronic', 'Electronic'),
  15. ('other', 'Other')],
  16. 'Type')
  17. notes = fields.Text('Internal Notes')
  18. descr = fields.Html('Description')
  19. # 数字字段
  20. copies = fields.Integer(default=1)
  21. avg_rating = fields.Float('Average Rating', (3,2))
  22. price = fields.Monetary('Price', 'currency_id')
  23. currency_id = fields.Many2one('res.currency') # price helper
  24. # 日期、时间字段
  25. date_published = fields.Date()
  26. last_borrow_date = fields.Datetime(
  27. 'Last Borrowed On',
  28. default=lambda self: fields.Datetime.now())
  29. # 其他字段
  30. active = fields.Boolean('Active?', default=True)
  31. image = fields.Binary('Cover')
  32. # 关系字段
  33. author_ids = fields.Many2many(
  34. 'res.partner', string='Authors')
  35. publisher_id = fields.Many2one(
  36. 'res.partner', string='Publisher')
  37. # 计算字段
  38. publisher_country_id = fields.Many2one(
  39. 'res.country', string='Publisher Country',
  40. compute='_compute_publisher_country',
  41. # store = False, # 默认不在数据库中存储
  42. inverse='_inverse_publisher_country',
  43. search='_search_publisher_country',
  44. )
  45. @api.depends('publisher_id.country_id')
  46. def _compute_publisher_country(self):
  47. for book in self:
  48. book.publisher_country_id = book.publisher_id.country_id
  49. # 计算字段执行写入
  50. def _inverse_publisher_country(self):
  51. for book in self:
  52. book.publisher_id.country_id = book.publisher_country_id
  53. # 计算字段搜索 域表达式使用publisher_id.country_id字段
  54. def _search_publisher_country(self, operator, value):
  55. return [('publisher_id.country_id', operator, value)]
  56. # python 模型约束
  57. @api.constrains('isbn')
  58. def _constrain_isbn_valid(self):
  59. for book in self:
  60. if book.isbn and not book._check_isbn():
  61. raise ValidationError('%s is an invalid ISBN' % book.isbn)
  62. def _check_isbn(self):
  63. self.ensure_one()
  64. isbn = self.isbn.replace('-', '') # 为保持兼容性 Alan 自行添加
  65. digits = [int(x) for x in isbn if x.isdigit()]
  66. if len(digits) == 13:
  67. ponderations = [1, 3] * 6
  68. terms = [a * b for a,b in zip(digits[:13], ponderations)]
  69. remain = sum(terms) % 10
  70. check = 10 - remain if remain !=0 else 0
  71. return digits[-1] == check
  72. def button_check_isbn(self):
  73. for book in self:
  74. if not book.isbn:
  75. raise Warning('Please provide an ISBN for %s' % book.name)
  76. if book.isbn and not book._check_isbn():
  77. raise Warning('%s is an invalid ISBN' % book.isbn)
  78. return True
  79. # 数据库约束
  80. _sql_constraints = [
  81. ('library_book_name_date_uq', # 约束唯一标识符
  82. 'UNIQUE (name, date_published)', # 约束 SQL 语法
  83. 'Book title and publication date must be unique'), # 消息
  84. ('library_book_check_date',
  85. 'CHECK (date_published <= current_date)',
  86. 'Publication date must not be in the future.'),
  87. ]
上海开阖软件有限公司 沪ICP备12045867号-1