Files
digest_app/module_project/mixins.py
2024-03-11 14:48:48 +05:30

118 lines
4.6 KiB
Python

from django.db.models import Q
from django.http.response import JsonResponse
from django.core.paginator import Paginator
from .utils import JsonResponseUtil
from django.views import generic
class DatatablesMixin:
"""
Mixin for handling Datatables parameters, filtering, sorting, pagination,
and response preparation.
"""
filter_fields = []
search_fields = []
def get_datatables_params(self, request):
"""
Extracts Datatables parameters from the request.
"""
draw = request.GET.get('draw', 1)
start = request.GET.get("start", 0)
length = request.GET.get("length", 10)
order_columns = request.GET.getlist('order[][column]')
order_directions = request.GET.getlist('order[][dir]')
search_value = request.GET.get("search[value]", "")
return draw, start, length, order_columns, order_directions, search_value
def get_filters(self, request):
"""
Extracts and applies filters based on request parameters.
"""
filters = {}
for field in self.filter_fields:
value = request.GET.get(field)
if value:
filters[field] = value
return filters
def get_sorting(self, request, order_columns, order_directions):
"""
Constructs the sorting order based on request parameters.
"""
sorting = []
for i in range(len(order_columns)):
column_index = int(order_columns[i])
order = order_directions[i]
field = self.model._meta.get_field(column_index).name
sorting.append('-' + field if order == 'desc' else field)
return sorting
def get_search_filters(self, request, search_value, search_fields):
"""
Generates Q objects for global and individual column search.
"""
search_filters = Q()
if search_value:
for field in search_fields:
search_filters |= Q(**{f'{field}__icontains': search_value})
if 'columns' in request.GET:
search_filters = Q()
for i, column_index in enumerate(request.GET.getlist('order[][column]')):
if request.GET.get(f'columns[{column_index}][search][value]'):
field = self.model._meta.get_field(int(column_index)).name
search_filters |= Q(**{f'{field}__icontains': request.GET.get(f'columns[{column_index}][search][value]')})
return search_filters
def get_pagination(self, queryset, start, length):
"""
Performs pagination based on the requested page and page size.
"""
paginator = Paginator(queryset, length)
page_number = (int(start) // int(length)) + 1
page_obj = paginator.page(page_number)
total_count = paginator.count
filtered_count = len(page_obj.object_list)
return page_obj, total_count, filtered_count
def prepare_datatables_response(self, draw, total_count, filtered_count, data):
"""
Prepares the JSON response for Datatables.
"""
return JsonResponse({
"draw": draw,
"recordsTotal": total_count,
"recordsFiltered": filtered_count,
"data": data
})
class ActionMixin(generic.View):
model = None
def post(self, request, *args, **kwargs):
if self.model is None:
raise NotImplementedError("Subclasses of BaseActionView must define a 'model' attribute.")
action = request.POST.get('action') # 'archive', 'active', or 'unarchive'
ids = request.POST.getlist('ids[]') # List of IDs to perform action on
active = request.POST.get('active')
print(f"arhive action {action} and id is {ids} and active data is {active}")
if action == 'archive':
# Update 'deleted' field to True for the selected users
self.model.objects.filter(id__in=ids).update(deleted=True, active=False)
message = 'Record archived successfully.'
elif action == 'active':
# Update 'active' field to True for the selected users
self.model.objects.filter(id__in=ids).update(active=active.capitalize())
message = 'Record updated successfully.'
elif action == 'unarchive':
# Update 'deleted' field to False for the selected users
self.model.objects.filter(id__in=ids).update(deleted=False)
message = 'Record unarchived successfully.'
else:
return JsonResponseUtil.error(message="Invalid Action")
return JsonResponseUtil.success(message=message)