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)
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
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 ''
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) }
def test_unsupported_request_method(): with pytest.raises(AssertionError): request_data(Struct(method='OPTIONS'))
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'