odoo_dev 开发培训作业:图书管理系统
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

101 lines
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