I've been asked to do some filters before passing the data to the website.
I have four(4) models that are linked with many2many fields. Let me add an image of the four models.
In order to print the model.a, we need to check if it has model.b linked to it, then check if some model.c is linked to model.b and finally, check if some model.d is linked to model.c. After all of that. The result is the same as this image
To do that, I wrote this code :
@http.route(['/agenda'], auth="public", website=True)
def agenda(self):
months = DATES_SELECT
# all dictionary used in the implementation
model_c_dict = {}
model_b_dict = {}
model_a_dict = {}
model_a_key = []
# filter the model.d according to certain condition
# should I set registrations_left field as store=True for performance when using .search()
model_d_ids = request.env['model.d'].search([('date_start', '>', dt.now().date()), ('state', '=', 'opened')], order="date_start").filtered(lambda k: k.registrations_left != 0)
for session in model_d_ids:
course_id = session.course_id_many[:1]
if not course_id.state == 'validated':
continue
model_c_dict.setdefault(course_id.id, {'object': course_id, 'sessions': []})
model_c_dict[course_id.id]['sessions'].append(session)
for k, v in model_c_dict.items():
category_id = v['object'].category_ids[:1]
if not category_id:
continue
model_b_dict.setdefault(category_id.id, {'object': category_id, 'course': {}})
model_b_dict[category_id.id]['course'].setdefault(k, v)
for k, v in model_b_dict.items():
catalogue_id = v['object'].catalogue_ids[:1]
if not catalogue_id:
continue
model_a_dict.setdefault(catalogue_id.id, {'object': catalogue_id, 'category': {}})
model_a_dict[catalogue_id.id]['category'].setdefault(k, v)
if catalogue_id.id in model_a_dict:
model_a_key.append(catalogue_id)
# sort the model_a with model_a.sequence as key
model_a_key = sorted(list(set(model_a_key)), key=lambda k: k.sequence)
# pack key
dict_key = {'model_a_key': model_a_key}
values = {
'months': months,
'categs': model_a_dict,
'dict_key': dict_key,
}
return request.render('website_custom.agenda', values)
It works as intended, but I don't know if It has performance issues, if it's bad coding, ...
So I'm asking your opinion.
PS: I didn't design the models and its relations.
I loved the slice technique to avoid index out of range error
, and can be very usefull to check if the record is connected
all the way up to A (catalogue model) in filtered function k.course_id_many[:1].category_ids[:1].catalogue_ids[:1]
but I prefer doing this in the domain:
@http.route(['/agenda'], auth="public", website=True)
def agenda(self):
courses_dict = {}
category_dict = {}
catalogue_dict = {}
# extract all record of Model D connected all the way up to A model
sessions = request.env['model.d'].search([('date_start', '>', dt.now().date()),
('state', '=', 'opened'),
# this will make sure that the record retrieved will be connected to catalogue model (A)
('course_id_many.category_ids.catalogue_ids', '!=', False)], order="date_start") \
.filtered(lambda k: k.registrations_left != 0)
for session in sessions:
# if you want to treat olny the first record you can add the slice on the many2many [:1]
# but I think you will skip the rest of the record in the many2many field
# and if this what you want the loop are not needed at all just do `course = session.course_id_many[0]`
# and do the same for all loops. because you don't have to check if the record are connected we all ready did that in search method
course = session.course_id_many[0]
if not course.state == 'validated': continue # skip validated courses
# add course to dict, and add the session to it's list of sessions
course_obj = courses_dict.setdefault(course.id, {'object': course, 'sessions': []})
course_obj['sessions'].append(session)
category = course.category_ids[0]
# store category, and add course to it's list of courses
category_obj = category_dict.setdefault(category.id, {'object': category, 'course': {}})
category_obj = category_dict[category.id]['course'][course.id] = course_obj
catalogue = category.catalogue_ids[0]
# sotre catalog, and add category to it's categories list
catalogue_dict.setdefault(catalogue.id, {'object': catalogue, 'category': {}})['category'][category.id] = category_obj
# sort catalogue
catalogue_keys = sorted(catalogue_dict.keys(), key=lambda k: catalogue_dict[k]['object'].sequence)
values = {
'months': DATES_SELECT,
'categs': catalogue_dict,
'dict_key': catalogue_keys,
}
return request.render('website_custom.agenda', values)
I hope this work I did the best to check for syntax errors, It should work.