示例#1
0
def test_model_and_rows():
    # Model only defaults to all()
    model, rows = model_and_rows(model=Foo, rows=None)
    assert model is Foo and str(rows.query) == str(Foo.objects.all().query)

    # rows is preserved and model is returned
    orig_rows = Foo.objects.filter(foo=2)
    model, rows = model_and_rows(model=None, rows=orig_rows)
    assert model is Foo and rows is orig_rows
示例#2
0
文件: query.py 项目: forksbot/iommi
    def _from_model(cls, *, rows=None, model=None, filters, include=None, exclude=None):
        assert rows is None or isinstance(rows, QuerySet), \
            'auto__rows needs to be a QuerySet for filter generation to work. ' \
            'If it needs to be a lambda, provide a model with auto__model for filter generation, ' \
            'and pass the lambda as rows.'

        model, rows = model_and_rows(model, rows)
        assert model is not None or rows is not None, "auto__model or auto__rows must be specified"
        filters = cls.filters_from_model(model=model, include=include, exclude=exclude, filters=filters)
        return model, rows, filters
示例#3
0
    def __init__(self,
                 *,
                 model=None,
                 rows=None,
                 filters=None,
                 _filters_dict=None,
                 auto,
                 **kwargs):
        assert isinstance(filters, dict)

        if auto:
            auto = QueryAutoConfig(**auto)
            auto_model, auto_rows, filters = self._from_model(
                model=auto.model,
                rows=auto.rows,
                filters=filters,
                include=auto.include,
                exclude=auto.exclude,
            )

            assert model is None, "You can't use the auto feature and explicitly pass model. " \
                                  "Either pass auto__model, or we will set the model for you from auto__rows"
            model = auto_model

            if rows is None:
                rows = auto_rows

        model, rows = model_and_rows(model, rows)

        setdefaults_path(
            kwargs,
            form__call_target=self.get_meta().form_class,
        )

        self._form = None
        self.query_advanced_value = None
        self.query_error = None

        super(Query, self).__init__(model=model, rows=rows, **kwargs)

        collect_members(self,
                        name='filters',
                        items=filters,
                        items_dict=_filters_dict,
                        cls=self.get_meta().member_class)

        field_class = self.get_meta().form_class.get_meta().member_class

        declared_fields = Struct()
        declared_fields[FREETEXT_SEARCH_NAME] = field_class(
            _name=FREETEXT_SEARCH_NAME,
            display_name='Search',
            required=False,
            include=False,
        )

        for name, filter in items(declared_members(self).filters):
            if filter.attr is None and getattr(filter.value_to_q,
                                               'iommi_needs_attr', False):
                continue
            field = setdefaults_path(
                Namespace(),
                filter.field,
                _name=name,
                model_field=filter.model_field,
                attr=name if filter.attr is MISSING else filter.attr,
                call_target__cls=field_class,
            )
            declared_fields[name] = field()

        # noinspection PyCallingNonCallable
        self.form: Form = self.form(
            _name='form',
            _fields_dict=declared_fields,
            attrs__method='get',
            actions__submit__attrs__value='Filter',
        )
        declared_members(self).form = self.form

        self.advanced_simple_toggle = Action(
            attrs__href='#',
            attrs__class__iommi_query_toggle_simple_mode=True,
            attrs={'data-advanced-mode': 'simple'},
            display_name='Switch to advanced search',
        )

        self.form_container = self.form_container()

        # Filters need to be at the end to not steal the short names
        set_declared_member(self, 'filters',
                            declared_members(self).pop('filters'))
示例#4
0
    def __init__(self,
                 *,
                 model=None,
                 rows=None,
                 filters=None,
                 _filters_dict=None,
                 auto=None,
                 **kwargs):
        assert isinstance(filters, dict)

        if auto:
            auto = QueryAutoConfig(**auto)
            auto_model, auto_rows, filters = self._from_model(
                model=auto.model,
                rows=auto.rows,
                filters=filters,
                include=auto.include,
                exclude=auto.exclude,
            )

            assert model is None, "You can't use the auto feature and explicitly pass model. " \
                                  "Either pass auto__model, or we will set the model for you from auto__rows"
            model = auto_model

            if rows is None:
                rows = auto_rows

        model, rows = model_and_rows(model, rows)

        setdefaults_path(
            kwargs,
            form__call_target=self.get_meta().form_class,
        )

        self.query_advanced_value = None
        self.query_error = None

        # Here we need to remove the freetext config from kwargs because we want to
        # handle it differently from the other fields.
        # BUT It's not safe to modify kwargs deeply! Because reinvoke() is evil:
        # It will call init again with the same kwargs + whatever additional kwargs
        # might have come from a parent or styling info.
        freetext_config = kwargs.get('form', {}).get('fields',
                                                     {}).get('freetext', {})
        if 'form' in kwargs and 'fields' in kwargs[
                'form'] and 'freetext' in kwargs['form']['fields']:
            # copy (just) the namespace so we can safely remove freetext from it
            kwargs = Namespace(flatten(Namespace(kwargs)))
            freetext_config = kwargs.get('form',
                                         {}).get('fields',
                                                 {}).pop('freetext', {})

        super(Query, self).__init__(model=model, rows=rows, **kwargs)

        collect_members(self,
                        name='filters',
                        items=filters,
                        items_dict=_filters_dict,
                        cls=self.get_meta().member_class)

        field_class = self.get_meta().form_class.get_meta().member_class

        declared_fields = Struct()
        declared_fields[FREETEXT_SEARCH_NAME] = field_class(
            _name=FREETEXT_SEARCH_NAME,
            display_name=gettext('Search'),
            required=False,
            include=False,
            help__include=False,
            **freetext_config)

        for name, filter in items(declared_members(self).filters):
            field = setdefaults_path(
                Namespace(),
                filter.field,
                _name=name,
                model_field=filter.model_field,
                attr=name if filter.attr is MISSING else filter.attr,
                call_target__cls=field_class,
                help__include=False,
            )
            declared_fields[name] = field()

        # noinspection PyCallingNonCallable
        self.form: Form = self.form(
            _name='form',
            _fields_dict=declared_fields,
            attrs__method='get',
            actions__submit=dict(
                attrs={'data-iommi-filter-button': ''},
                display_name=gettext('Filter'),
            ),
        )
        declared_members(self).form = self.form

        self.advanced = declared_members(self).advanced = self.advanced(
            _name='advanced')

        self.form_container = self.form_container(_name='form_container')

        # Filters need to be at the end to not steal the short names
        set_declared_member(self, 'filters',
                            declared_members(self).pop('filters'))