Ejemplo n.º 1
0
    def on_bind(self) -> None:
        assert self.actions_template
        self._valid = None
        request = self.get_request()
        self._request_data = request_data(request)

        self.title = evaluate_strict(self.title, **self.iommi_evaluate_parameters())
        if isinstance(self.h_tag, Namespace):
            if self.title not in (None, MISSING):
                self.h_tag = self.h_tag(
                    _name='h_tag',
                    children__text=capitalize(self.title),
                ).bind(parent=self)
            else:
                self.h_tag = ''
        else:
            self.h_tag = self.h_tag.bind(parent=self)

        # Actions have to be bound first because is_target() needs it
        bind_members(self, name='actions', cls=Actions)

        if self._request_data is not None and self.is_target():
            self.mode = FULL_FORM_FROM_REQUEST

        bind_members(self, name='fields')
        bind_members(self, name='endpoints')

        self.is_valid()

        self.errors = Errors(parent=self, errors=self.errors)
Ejemplo n.º 2
0
    def on_bind(self) -> None:
        bind_members(self, name='filters')
        self.advanced_simple_toggle = self.advanced_simple_toggle.bind(parent=self)

        request = self.get_request()
        self.query_advanced_value = request_data(request).get(self.get_advanced_query_param(), '') if request else ''

        # TODO: should it be possible to have freetext as a callable? this code just treats callables as truthy
        if any(f.freetext for f in values(declared_members(self)['filters'])):
            declared_members(self.form).fields[FREETEXT_SEARCH_NAME].include = True

        declared_fields = declared_members(self.form)['fields']
        for name, filter in items(self.filters):
            assert filter.attr or not getattr(filter.value_to_q, 'iommi_needs_attr', False), f"{name} cannot be a part of a query, it has no attr or value_to_q so we don't know what to search for"
            if name in declared_fields:
                field = setdefaults_path(
                    Namespace(),
                    _name=name,
                    attr=name if filter.attr is MISSING else filter.attr,
                    model_field=filter.model_field,
                )
                declared_fields[name] = declared_fields[name].reinvoke(field)
        set_declared_member(self.form, 'fields', declared_fields)
        for name, field in items(declared_fields):
            if name == FREETEXT_SEARCH_NAME:
                continue
            if name not in self.filters:
                field.include = False

        bind_members(self, name='endpoints')

        self.form = self.form.bind(parent=self)
        self._bound_members.form = self.form
Ejemplo n.º 3
0
    def get_query_string(self):
        """
        Based on the data in the request, return the equivalent query string that you can use with parse_query_string() to create a query set.
        """
        form = self.form
        request = self.get_request()

        if request is None:
            return ''

        if request_data(request).get(self.get_advanced_query_param(), '').strip():
            return request_data(request).get(self.get_advanced_query_param())
        elif form.is_valid():

            def expr(field, is_list, value):
                if is_list:
                    return '(' + ' OR '.join([expr(field, is_list=False, value=x) for x in field.value]) + ')'
                return build_query_expression(filter=self.filters[field._name], value=value)

            result = [
                expr(field, field.is_list, field.value)
                for field in values(form.fields)
                if field._name != FREETEXT_SEARCH_NAME
                and field._name in self.filters
                and field.value not in (None, '', [])
            ]

            if FREETEXT_SEARCH_NAME in form.fields:
                freetext = form.fields[FREETEXT_SEARCH_NAME].value
                if freetext:
                    result.append(
                        '(%s)'
                        % ' or '.join(
                            [
                                f'{filter.query_name}:{to_string_surrounded_by_quote(freetext)}'
                                for filter in values(self.filters)
                                if filter.freetext
                            ]
                        )
                    )
            return ' and '.join(result)
        else:
            return ''
Ejemplo n.º 4
0
    def on_bind(self) -> None:
        bind_members(self, name='filters')

        request = self.get_request()
        self.query_advanced_value = request_data(request).get(
            self.get_advanced_query_param(), '') if request else ''

        # TODO: should it be possible to have freetext as a callable? this code just treats callables as truthy
        if any(f.freetext for f in values(declared_members(self)['filters'])):
            set_and_remember_for_reinvoke(declared_members(
                self.form).fields[FREETEXT_SEARCH_NAME],
                                          include=True)

        declared_fields = declared_members(self.form)['fields']
        for name, filter in items(self.filters):
            is_valid, message = filter.is_valid_filter(name=name,
                                                       filter=filter)
            assert is_valid, message
            if name in declared_fields:
                field = setdefaults_path(
                    Namespace(),
                    _name=name,
                    attr=name if filter.attr is MISSING else filter.attr,
                    model_field=filter.model_field,
                    help__include=False,
                )
                declared_fields[name] = reinvoke(declared_fields[name], field)
        set_declared_member(self.form, 'fields', declared_fields)

        # Remove fields from the form that correspond to non-included filters
        declared_filters = declared_members(self)['filters']
        for name, field in items(declared_fields):
            if name == FREETEXT_SEARCH_NAME:
                continue
            # We need to check if it's in declared_filters first, otherwise we remove any injected fields
            if name in declared_filters and name not in self.filters:
                set_and_remember_for_reinvoke(field, include=False)

        bind_members(self, name='endpoints')

        self.form = self.form.bind(parent=self)
        self._bound_members.form = self.form

        self.advanced = self._bound_members.advanced = self.advanced.bind(
            parent=self)

        self.form_container = self.form_container.bind(parent=self)

        self.filter_name_by_query_name = {
            x.query_name: name
            for name, x in items(self.filters)
        }
Ejemplo n.º 5
0
def test_unsupported_request_method():
    with pytest.raises(AssertionError):
        request_data(Struct(method='OPTIONS'))
Ejemplo n.º 6
0
def test_request_data():
    r = Struct(method='POST', POST='POST', GET='GET')
    assert request_data(r) == 'POST'
    r.method = 'GET'
    assert request_data(r) == 'GET'