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)