オープンアカデミーのデータモデル

7 minute read

データモデル

モデルソースコード

modules.py - Course

class Course(models.Model):
    _name = 'openacademy.course'
    _description = "OpenAcademy Courses"

    name = fields.Char(string="Title", required=True)
    description = fields.Text()

    responsible_id = fields.Many2one('res.users',
        ondelete='set null', string="Responsible", index=True)
    session_ids = fields.One2many(
        'openacademy.session', 'course_id', string="Sessions")

    def copy(self, default=None):
        default = dict(default or {})

        copied_count = self.search_count(
            [('name', '=like', _(u"Copy of {}%").format(self.name))])
        if not copied_count:
            new_name = _(u"Copy of {}").format(self.name)
        else:
            new_name = _(u"Copy of {} ({})").format(self.name, copied_count)

        default['name'] = new_name
        return super(Course, self).copy(default)

    _sql_constraints = [
        ('name_description_check',
         'CHECK(name != description)',
         "The title of the course should not be the description"),

        ('name_unique',
         'UNIQUE(name)',
         "The course title must be unique"),
    ]

modules.py - Session

class Session(models.Model):
    _name = 'openacademy.session'
    _description = "OpenAcademy Sessions"

    name = fields.Char(required=True)
    start_date = fields.Date(default=fields.Date.today)
    duration = fields.Float(digits=(6, 2), help="Duration in days")
    seats = fields.Integer(string="Number of seats")
    active = fields.Boolean(default=True)
    color = fields.Integer()

    instructor_id = fields.Many2one('res.partner', string="Instructor",
        domain=['|', ('instructor', '=', True),
                     ('category_id.name', 'ilike', "Teacher")])
    course_id = fields.Many2one('openacademy.course',
        ondelete='cascade', string="Course", required=True)
    attendee_ids = fields.Many2many('res.partner', string="Attendees")

    taken_seats = fields.Float(string="Taken seats", compute='_taken_seats')
    end_date = fields.Date(string="End Date", store=True,
        compute='_get_end_date', inverse='_set_end_date')

    hours = fields.Float(string="Duration in hours",
                         compute='_get_hours', inverse='_set_hours')

    attendees_count = fields.Integer(
        string="Attendees count", compute='_get_attendees_count', store=True)

    @api.depends('seats', 'attendee_ids')
    def _taken_seats(self):
        for r in self:
            if not r.seats:
                r.taken_seats = 0.0
            else:
                r.taken_seats = 100.0 * len(r.attendee_ids) / r.seats

    @api.onchange('seats', 'attendee_ids')
    def _verify_valid_seats(self):
        if self.seats < 0:
            return {
                'warning': {
                    'title': _("Incorrect 'seats' value"),
                    'message': _("The number of available seats may not be negative"),
                },
            }
        if self.seats < len(self.attendee_ids):
            return {
                'warning': {
                    'title': _("Too many attendees"),
                    'message': _("Increase seats or remove excess attendees"),
                },
            }

    @api.depends('start_date', 'duration')
    def _get_end_date(self):
        for r in self:
            if not (r.start_date and r.duration):
                r.end_date = r.start_date
                continue

            # Add duration to start_date, but: Monday + 5 days = Saturday, so
            # subtract one second to get on Friday instead
            duration = timedelta(days=r.duration, seconds=-1)
            r.end_date = r.start_date + duration

    def _set_end_date(self):
        for r in self:
            if not (r.start_date and r.end_date):
                continue

            # Compute the difference between dates, but: Friday - Monday = 4 days,
            # so add one day to get 5 days instead
            r.duration = (r.end_date - r.start_date).days + 1

    @api.depends('duration')
    def _get_hours(self):
        for r in self:
            r.hours = r.duration * 24

    def _set_hours(self):
        for r in self:
            r.duration = r.hours / 24

    @api.depends('attendee_ids')
    def _get_attendees_count(self):
        for r in self:
            r.attendees_count = len(r.attendee_ids)

    @api.constrains('instructor_id', 'attendee_ids')
    def _check_instructor_not_in_attendees(self):
        for r in self:
            if r.instructor_id and r.instructor_id in r.attendee_ids:
                raise exceptions.ValidationError(_("A session's instructor can't be an attendee"))

wizard.py - Wizard

class Wizard(models.TransientModel):
    _name = 'openacademy.wizard'
    _description = "Wizard: Quick Registration of Attendees to Sessions"

    def _default_sessions(self):
        return self.env['openacademy.session'].browse(self._context.get('active_ids'))

    session_ids = fields.Many2many('openacademy.session',
        string="Sessions", required=True, default=_default_sessions)
    attendee_ids = fields.Many2many('res.partner', string="Attendees")

    def subscribe(self):
        for session in self.session_ids:
            session.attendee_ids |= self.attendee_ids
        return {}

テーブル一覧

生成されたテーブル

Table Name 内容
openacademy_course  
openacademy_session  
openacademy_session_res_partner_rel Many2many()
openacademy_session_openacademy_wizard_rel Many2many()
openacademy_wizard  
openacademy_wizard_res_partner_rel Many2many()

拡張されたテーブル

Table Name 内容
res_partner instructor フィールドを追加

テーブル - openacademy_course

Column Type Collation Nullable Default
id integer   not null nextval(‘openacademy_course_id_seq’::regclass)
name character varying   not null  
description text      
responsible_id integer      
create_uid integer      
create_date timestamp without time zone      
write_uid integer      
write_date timestamp without time zone      
Indexes:
    "openacademy_course_pkey" PRIMARY KEY, btree (id)
    "openacademy_course_name_unique" UNIQUE CONSTRAINT, btree (name)
    "openacademy_course_responsible_id_index" btree (responsible_id)
Check constraints:
    "openacademy_course_name_description_check" CHECK (name::text <> description)
Foreign-key constraints:
    "openacademy_course_create_uid_fkey" FOREIGN KEY (create_uid) REFERENCES res_users(id) ON DELETE SET NULL
    "openacademy_course_responsible_id_fkey" FOREIGN KEY (responsible_id) REFERENCES res_users(id) ON DELETE SET NULL
    "openacademy_course_write_uid_fkey" FOREIGN KEY (write_uid) REFERENCES res_users(id) ON DELETE SET NULL
Referenced by:
    TABLE "openacademy_session" CONSTRAINT "openacademy_session_course_id_fkey" FOREIGN KEY (course_id) REFERENCES openacademy_course(id) ON DELETE CASCADE

テーブル - openacademy_session

Column Type Collation Nullable Default
id integer   not null nextval(‘openacademy_session_id_seq’::regclass)
name character varying   not null  
start_date date      
duration numeric      
seats integer      
active boolean      
color integer      
instructor_id integer      
course_id integer   not null  
end_date date      
attendees_count integer      
create_uid integer      
create_date timestamp without time zone      
write_uid integer      
write_date timestamp without time zone      
Indexes:
    "openacademy_session_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "openacademy_session_course_id_fkey" FOREIGN KEY (course_id) REFERENCES openacademy_course(id) ON DELETE CASCADE
    "openacademy_session_create_uid_fkey" FOREIGN KEY (create_uid) REFERENCES res_users(id) ON DELETE SET NULL
    "openacademy_session_instructor_id_fkey" FOREIGN KEY (instructor_id) REFERENCES res_partner(id) ON DELETE SET NULL
    "openacademy_session_write_uid_fkey" FOREIGN KEY (write_uid) REFERENCES res_users(id) ON DELETE SET NULL
Referenced by:
    TABLE "openacademy_session_openacademy_wizard_rel" CONSTRAINT "openacademy_session_openacademy_wiz_openacademy_session_id_fkey" FOREIGN KEY (openacademy_session_id) REFERENCES openacademy_session(id) ON DELETE CASCADE
    TABLE "openacademy_session_res_partner_rel" CONSTRAINT "openacademy_session_res_partner_rel_openacademy_session_id_fkey" FOREIGN KEY (openacademy_session_id) REFERENCES openacademy_session(id) ON DELETE CASCADE

テーブル - openacademy_session_res_partner_rel”

Column Type Collation Nullable Default
openacademy_session_id integer   not null  
res_partner_id integer   not null  
Indexes:
    "openacademy_session_res_partn_openacademy_session_id_res_pa_key" UNIQUE CONSTRAINT, btree (openacademy_session_id, res_partner_id)
    "openacademy_session_res_partner_rel_openacademy_session_id_idx" btree (openacademy_session_id)
    "openacademy_session_res_partner_rel_res_partner_id_idx" btree (res_partner_id)
Foreign-key constraints:
    "openacademy_session_res_partner_rel_openacademy_session_id_fkey" FOREIGN KEY (openacademy_session_id) REFERENCES openacademy_session(id) ON DELETE CASCADE
    "openacademy_session_res_partner_rel_res_partner_id_fkey" FOREIGN KEY (res_partner_id) REFERENCES res_partner(id) ON DELETE CASCADE

テーブル - openacademy_wizard

Column Type Collation Nullable Default
id integer   not null nextval(‘openacademy_wizard_id_seq’::regclass)
create_uid integer      
create_date timestamp without time zone      
write_uid integer      
write_date timestamp without time zone      
Indexes:
    "openacademy_wizard_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "openacademy_wizard_create_uid_fkey" FOREIGN KEY (create_uid) REFERENCES res_users(id) ON DELETE SET NULL
    "openacademy_wizard_write_uid_fkey" FOREIGN KEY (write_uid) REFERENCES res_users(id) ON DELETE SET NULL
Referenced by:
    TABLE "openacademy_session_openacademy_wizard_rel" CONSTRAINT "openacademy_session_openacademy_wiza_openacademy_wizard_id_fkey" FOREIGN KEY (openacademy_wizard_id) REFERENCES openacademy_wizard(id) ON DELETE CASCADE
    TABLE "openacademy_wizard_res_partner_rel" CONSTRAINT "openacademy_wizard_res_partner_rel_openacademy_wizard_id_fkey" FOREIGN KEY (openacademy_wizard_id) REFERENCES openacademy_wizard(id) ON DELETE CASCADE

テーブル - openacademy_wizard_res_partner_rel

Column Type Collation Nullable Default
openacademy_wizard_id integer   not null  
res_partner_id integer   not null  
Indexes:
    "openacademy_wizard_res_partne_openacademy_wizard_id_res_par_key" UNIQUE CONSTRAINT, btree (openacademy_wizard_id, res_partner_id)
    "openacademy_wizard_res_partner_rel_openacademy_wizard_id_idx" btree (openacademy_wizard_id)
    "openacademy_wizard_res_partner_rel_res_partner_id_idx" btree (res_partner_id)
Foreign-key constraints:
    "openacademy_wizard_res_partner_rel_openacademy_wizard_id_fkey" FOREIGN KEY (openacademy_wizard_id) REFERENCES openacademy_wizard(id) ON DELETE CASCADE
    "openacademy_wizard_res_partner_rel_res_partner_id_fkey" FOREIGN KEY (res_partner_id) REFERENCES res_partner(id) ON DELETE CASCADE

テーブル - res_partner”

Column Type Collation Nullable Default
id integer   not null nextval(‘res_partner_id_seq’::regclass)
name character varying      
company_id integer      
create_date timestamp without time zone      
display_name character varying      
date date      
title integer      
parent_id integer      
ref character varying      
lang character varying      
tz character varying      
user_id integer      
vat character varying      
website character varying      
comment text      
credit_limit double precision      
active boolean      
employee boolean      
function character varying      
type character varying      
street character varying      
street2 character varying      
zip character varying      
city character varying      
state_id integer      
country_id integer      
partner_latitude numeric      
partner_longitude numeric      
email character varying      
phone character varying      
mobile character varying      
is_company boolean      
industry_id integer      
color integer      
partner_share boolean      
commercial_partner_id integer      
commercial_company_name character varying      
company_name character varying      
create_uid integer      
write_uid integer      
write_date timestamp without time zone      
instructor boolean      
Indexes:
    "res_partner_pkey" PRIMARY KEY, btree (id)
    "res_partner_commercial_partner_id_index" btree (commercial_partner_id)
    "res_partner_company_id_index" btree (company_id)
    "res_partner_date_index" btree (date)
    "res_partner_display_name_index" btree (display_name)
    "res_partner_name_index" btree (name)
    "res_partner_parent_id_index" btree (parent_id)
    "res_partner_ref_index" btree (ref)
    "res_partner_vat_index" btree (regexp_replace(upper(vat::text), '[^A-Z0-9]+'::text, ''::text, 'g'::text))
Check constraints:
    "res_partner_check_name" CHECK (type::text = 'contact'::text AND name IS NOT NULL OR type::text <> 'contact'::text)
Foreign-key constraints:
    "res_partner_commercial_partner_id_fkey" FOREIGN KEY (commercial_partner_id) REFERENCES res_partner(id) ON DELETE SE
T NULL
    "res_partner_company_id_fkey" FOREIGN KEY (company_id) REFERENCES res_company(id) ON DELETE SET NULL
    "res_partner_country_id_fkey" FOREIGN KEY (country_id) REFERENCES res_country(id) ON DELETE RESTRICT
    "res_partner_create_uid_fkey" FOREIGN KEY (create_uid) REFERENCES res_users(id) ON DELETE SET NULL
    "res_partner_industry_id_fkey" FOREIGN KEY (industry_id) REFERENCES res_partner_industry(id) ON DELETE SET NULL
    "res_partner_parent_id_fkey" FOREIGN KEY (parent_id) REFERENCES res_partner(id) ON DELETE SET NULL
    "res_partner_state_id_fkey" FOREIGN KEY (state_id) REFERENCES res_country_state(id) ON DELETE RESTRICT
    "res_partner_title_fkey" FOREIGN KEY (title) REFERENCES res_partner_title(id) ON DELETE SET NULL
    "res_partner_user_id_fkey" FOREIGN KEY (user_id) REFERENCES res_users(id) ON DELETE SET NULL
    "res_partner_write_uid_fkey" FOREIGN KEY (write_uid) REFERENCES res_users(id) ON DELETE SET NULL
Referenced by:
    TABLE "base_partner_merge_automatic_wizard" CONSTRAINT "base_partner_merge_automatic_wizard_dst_partner_id_fkey" FOR
EIGN KEY (dst_partner_id) REFERENCES res_partner(id) ON DELETE SET NULL
    TABLE "base_partner_merge_automatic_wizard_res_partner_rel" CONSTRAINT "base_partner_merge_automatic_wizard_res_par_
res_partner_id_fkey" FOREIGN KEY (res_partner_id) REFERENCES res_partner(id) ON DELETE CASCADE
    TABLE "openacademy_session" CONSTRAINT "openacademy_session_instructor_id_fkey" FOREIGN KEY (instructor_id) REFERENC
ES res_partner(id) ON DELETE SET NULL
    TABLE "openacademy_session_res_partner_rel" CONSTRAINT "openacademy_session_res_partner_rel_res_partner_id_fkey" FOR
EIGN KEY (res_partner_id) REFERENCES res_partner(id) ON DELETE CASCADE
    TABLE "openacademy_wizard_res_partner_rel" CONSTRAINT "openacademy_wizard_res_partner_rel_res_partner_id_fkey" FOREI
GN KEY (res_partner_id) REFERENCES res_partner(id) ON DELETE CASCADE
    TABLE "res_company" CONSTRAINT "res_company_partner_id_fkey" FOREIGN KEY (partner_id) REFERENCES res_partner(id) ON
DELETE RESTRICT
    TABLE "res_partner_bank" CONSTRAINT "res_partner_bank_partner_id_fkey" FOREIGN KEY (partner_id) REFERENCES res_partn
er(id) ON DELETE CASCADE
    TABLE "res_partner" CONSTRAINT "res_partner_commercial_partner_id_fkey" FOREIGN KEY (commercial_partner_id) REFERENC
ES res_partner(id) ON DELETE SET NULL
    TABLE "res_partner" CONSTRAINT "res_partner_parent_id_fkey" FOREIGN KEY (parent_id) REFERENCES res_partner(id) ON DE
LETE SET NULL
    TABLE "res_partner_res_partner_category_rel" CONSTRAINT "res_partner_res_partner_category_rel_partner_id_fkey" FOREI
GN KEY (partner_id) REFERENCES res_partner(id) ON DELETE CASCADE
    TABLE "res_users" CONSTRAINT "res_users_partner_id_fkey" FOREIGN KEY (partner_id) REFERENCES res_partner(id) ON DELE
TE RESTRICT

カテゴリー:

更新日時: