Files
ihrm/recruitment/pipeline_grouper.py

126 lines
4.2 KiB
Python

"""
pipeline_grouper.py
This module is used to make queryset by groups
"""
from datetime import datetime
from django.core.paginator import Paginator
from django.db import models
from django.db.models.fields.related_descriptors import ForwardManyToOneDescriptor
from horilla.horilla_middlewares import _thread_locals
def record_queryset_paginator(request, queryset, page_name, records_per_page=10):
"""
This method is used to return the paginator entries
"""
page = request.GET.get(page_name)
queryset = Paginator(queryset, records_per_page)
queryset = queryset.get_page(page)
return queryset
def generate_groups(request, groupers, queryset, page_name, group_field, is_fk_field):
"""
groups generating method
"""
groups = []
if is_fk_field:
for grouper in groupers:
group_queryset = queryset.filter(**{group_field: grouper.id})
# to avoid zero records groupings
if group_queryset.count():
group_info = {
"grouper": grouper,
"list": record_queryset_paginator(
request,
group_queryset,
f"dynamic_page_{page_name}{grouper.id}",
),
"dynamic_name": f"dynamic_page_{page_name}{grouper.id}",
}
groups.append(group_info)
else:
for grouper in groupers:
group_queryset = queryset.filter(**{group_field: grouper})
# to avoid zero records groupings
if group_queryset.count():
group = {
"grouper": grouper,
"list": record_queryset_paginator(
request,
group_queryset,
f"dynamic_page_{page_name}{grouper}".replace(" ", "_"),
),
"dynamic_name": f"dynamic_page_{page_name}{grouper}".replace(
" ", "_"
),
}
groups.append(group)
return groups
def group_by_queryset(
queryset, group_field, page=None, page_name="page", records_per_page=50
):
"""
This method is used to make group-by and split groups by nested pagination
"""
fields_split = group_field.split("__")
splited = len(fields_split) > 1
model = queryset.model
is_fk_field = isinstance(
getattr(model, group_field, None), ForwardManyToOneDescriptor
)
model_copy = model
field_obj = None
# geting request from the thread locals
request = getattr(_thread_locals, "request", None)
if splited or is_fk_field:
for field in fields_split:
field_obj = model_copy._meta.get_field(field)
model_copy = field_obj.related_model
if model_copy:
groupers = model_copy.objects.all()
groups = generate_groups(
request,
groupers,
queryset,
page_name,
group_field,
is_fk_field=True,
)
else:
groupers = [
item
for index, item in enumerate(
queryset.values_list(group_field, flat=True)
)
if item not in queryset.values_list(group_field, flat=True)[:index]
]
groups = generate_groups(
request, groupers, queryset, page_name, group_field, is_fk_field=False
)
else:
# making unique | not using set(groupers) due to ordering issue
groupers = [
item
for index, item in enumerate(queryset.values_list(group_field, flat=True))
if item not in queryset.values_list(group_field, flat=True)[:index]
]
related_model = queryset.model._meta.get_field(group_field).related_model
if related_model:
groupers = related_model.objects.filter(id__in=groupers)
groups = generate_groups(
request, groupers, queryset, page_name, group_field, is_fk_field=False
)
# getting related queryset
groups = Paginator(groups, records_per_page)
return groups.get_page(page)