Example #1
0
    def filter(self, qs):
        filterscount = int(self.request.GET.get('filterscount', 0))
        # server-side filtering
        if filterscount:
            filters = dict()
            for filter_num in range(filterscount):
                num = str(filter_num)
                field = self.request.GET.get('filterdatafield' + num).replace(
                    '-', '_')
                field = self.field_name_transform_map.get(field, field)
                value = (self.get_field_types() or self.field_types).get(
                    field, str)(self.request.GET.get('filtervalue' + num))
                condition = self.request.GET.get('filtercondition' + num)
                op = int(self.request.GET.get('filteroperator' + num, 0))
                if not filters.get(field):
                    filters[field] = list()
                filters[field].append(
                    dict(value=value, condition=condition, operator=op))
            q_all = Q()
            q_all.op = 1  # 0 - AND, 1 - OR
            for field in filters:
                for field_condition in filters[field]:

                    cond = field_condition['condition']
                    val = field_condition['value']
                    op = field_condition['operator']  # 0 - AND, 1 - OR

                    q_curr = Q()

                    # TODO: check if bool/null filter improved in new jqWidgets grid
                    # if vale is False filter None and False
                    if (self.get_field_types() or self.field_types).get(
                            field, str).__name__ == 'bool_lookup':
                        if cond == 'NOT_EQUAL' and val is True or cond == 'EQUAL' and val is False:
                            q_curr = Q(**{field: False}) | Q(
                                **{'%s__isnull' % field: True})
                        else:
                            q_curr = Q(**{field: True})
                    elif cond in self.conditions:
                        cond_str = '%s__%s' % (field, self.conditions[cond])
                        q_curr = Q(**{cond_str: val})
                    elif cond in self.conditions_empty:
                        cond_str = '%s__%s' % (field,
                                               self.conditions_empty[cond][0])
                        val = self.conditions_empty[cond][1]
                        q_curr = Q(**{cond_str: val})
                    elif cond in self.conditions_neg:
                        cond_str = '%s__%s' % (field,
                                               self.conditions_neg[cond])
                        q_curr = ~Q(**{cond_str: val})
                    # filter out empty and None values as well
                    elif cond == 'NOT_EMPTY':
                        q_curr = ~Q(**{field: ''}) & Q(
                            **{'%s__isnull' % field: False})

                    q_all = q_all | q_curr if q_all.op else q_all & q_curr
                    q_all.op = op

            qs = qs.filter(q_all)
        return qs
Example #2
0
    def get_queryset(self):
        filters = self.get_entries_filters()

        queryset = get_filtered_entries(self.request.user,
                                        filters).select_related(
                                            'lead',
                                            'lead__attachment',
                                            'controlled_changed_by',
                                        ).prefetch_related('lead__assignee')
        queryset = Entry.annotate_comment_count(queryset)

        project = filters.get('project')
        search = filters.get('search')

        if search:
            # For searching tabular columns
            field_filters = {}
            if project:
                field_filters['sheet__book__project'] = project

            fields = TabularField.objects.filter(title__icontains=search,
                                                 **field_filters)
            queryset = queryset.filter(
                models.Q(lead__title__icontains=search)
                | models.Q(excerpt__icontains=search)
                | (models.Q(tabular_field__in=models.Subquery(
                    fields.values_list('pk', flat=True)))))

        return (queryset.select_related(
            'image',
            'lead',
            'created_by__profile',
            'modified_by__profile',
        ).prefetch_related(
            'attribute_set',
            'lead__authors',
            'lead__assignee',
            'lead__assignee__profile',
            'lead__leadpreview',
        ))
Example #3
0
 def read_request_filters(self) -> Dict[str, Any]:
     filterscount = int(self.request.GET.get('filterscount', 0))
     # server-side filtering
     filters = dict()
     if filterscount:
         for filter_num in range(filterscount):
             num = str(filter_num)
             field = self.request.GET.get('filterdatafield' + num).replace('-', '_')
             field = self.field_name_transform_map.get(field, field)
             value = (self.get_field_types() or self.field_types).get(field, str)(
                 self.request.GET.get('filtervalue' + num))
             condition = self.request.GET.get('filtercondition' + num)
             op = int(self.request.GET.get('filteroperator' + num, 0))
             if not filters.get(field):
                 filters[field] = list()
             filters[field].append(dict(value=value, condition=condition, operator=op))
     return filters
Example #4
0
    def post(self, request, version=None):
        filters = request.data.get('filters', [])
        filters = {f[0]: f[1] for f in filters}

        queryset = get_filtered_entries(request.user, filters)

        search = filters.get('search')
        if search:
            queryset = queryset.filter(
                models.Q(lead__title__icontains=search)
                | models.Q(excerpt__icontains=search))

        queryset = EntryFilterSet(filters, queryset=queryset).qs

        page = self.paginate_queryset(queryset)

        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return response.Response(serializer.data)
Example #5
0
    def get_counts_by_matrix_2d(self, qs):
        # Project should be provided
        filters = self.get_entries_filters()
        project = filters.get('project')
        if project is None:
            return {}

        # Pull necessary widgets
        widgets = Widget.objects.filter(analysis_framework__project=project,
                                        widget_id__in=[
                                            matrix1d_widget.WIDGET_ID,
                                            matrix2d_widget.WIDGET_ID
                                        ]).values_list('key', 'widget_id',
                                                       'properties')

        # Pull necessary filters
        filters = {
            filter.key: filter
            for filter in Filter.objects.filter(
                analysis_framework__project=project,
                key__in=[
                    _key for key, widget_id, _ in widgets for _key in (
                        [f'{key}-dimensions', f'{key}-sectors'] if widget_id ==
                        matrix2d_widget.WIDGET_ID else [key])
                ])
        }

        # Calculate count
        agg_data = qs.aggregate(
            **{
                f"{key}__{ele['id' if widget_id == matrix2d_widget.WIDGET_ID else 'key']}__{control_status}":
                models.Count(
                    'id',
                    filter=models.Q(
                        controlled=control_status == 'controlled',
                        filterdata__filter=(
                            filters[f'{key}-{data_type}' if widget_id ==
                                    matrix2d_widget.WIDGET_ID else key]),
                        filterdata__values__contains=[
                            ele['id' if widget_id ==
                                matrix2d_widget.WIDGET_ID else 'key']
                        ],
                    ),
                    distinct=True,
                )
                for key, widget_id, properties in widgets
                for data_type in (['sectors', 'dimensions'] if widget_id ==
                                  matrix2d_widget.WIDGET_ID else ['rows'])
                for _ele in properties['data'][data_type] for ele in [
                    _ele, *(
                        _ele.get(f'sub{data_type}' if widget_id ==
                                 matrix2d_widget.WIDGET_ID else 'cells') or [])
                ] for control_status in ['controlled', 'uncontrolled']
            })

        # Re-structure data (also snake-case to camel case conversion will change the key)
        response = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
        for key, count in agg_data.items():
            widget_key, label_key, controlled_status = key.split('__')
            response[widget_key][label_key][controlled_status] = count
        return [{
            'widget_key': widget_key,
            'label_key': label_key,
            'controlled_count': count['controlled'],
            'uncontrolled_count': count['uncontrolled'],
        } for widget_key, widget_data in response.items()
                for label_key, count in widget_data.items()]