Пример #1
0
    def test_only_query_field_list_and_exclude_id(self):
        query = QueryFieldList(['name'],
                               value=QueryFieldList.ONLY,
                               _only_called=True) + QueryFieldList(
                                   ['_id'], value=QueryFieldList.EXCLUDE)

        expect(query.as_dict()).to_be_like({'_id': 0, 'name': 1})
Пример #2
0
    def test_gets_proper_type(self):
        query1 = QueryFieldList()
        query2 = QueryFieldList()

        expect(query1).to_be_instance_of(QueryFieldList)

        query = query1 + query2

        expect(query).to_be_instance_of(QueryFieldList)
Пример #3
0
    def test_union_of_excludes(self):
        query = (
            QueryFieldList(['name'], value=QueryFieldList.EXCLUDE) +
            QueryFieldList(['email', 'numbers'], value=QueryFieldList.EXCLUDE))

        expect(query.as_dict()).to_be_like({
            'name': 0,
            'email': 0,
            'numbers': 0
        })
Пример #4
0
    def test_slice_with_only_and_exclude(self):
        query = (QueryFieldList() + QueryFieldList(
            ['numbers'], value={'$slice': 10}, _only_called=False) +
                 QueryFieldList(['numbers'], value=QueryFieldList.EXCLUDE))

        expect(query.as_dict()).to_be_like({})

        # slice is assumed to act like only
        query = (QueryFieldList() + QueryFieldList(
            ['numbers'], value={'$slice': 10}, _only_called=False) +
                 QueryFieldList(
                     ['name'], value=QueryFieldList.ONLY, _only_called=True))

        expect(query.as_dict()).to_be_like({
            'name': 1,
            'numbers': {
                '$slice': 10
            }
        })

        query = (
            QueryFieldList() + QueryFieldList(
                ['numbers'], value={'$slice': 10}, _only_called=False) +
            QueryFieldList(['name'], value={'$slice': 13}, _only_called=False))

        expect(query.as_dict()).to_be_like({
            'numbers': {
                '$slice': 10
            },
            'name': {
                '$slice': 13
            }
        })
Пример #5
0
    def test_always_include(self):
        query = QueryFieldList(always_include=['email'])
        query += QueryFieldList(['name'],
                                value=QueryFieldList.ONLY,
                                _only_called=True)

        expect(query.as_dict()).to_be_like({'name': 1, 'email': 1})

        query = QueryFieldList(always_include=['email', 'name'],
                               value=QueryFieldList.EXCLUDE)
        query += QueryFieldList(['email'], value=QueryFieldList.EXCLUDE)

        expect(query.as_dict()).to_be_like({})
Пример #6
0
    def fields(self, _only_called=False, **kwargs):
        from itertools import groupby
        from operator import itemgetter

        operators = ['slice']
        cleaned_fields = []
        for key, value in kwargs.items():
            parts = key.split('__')
            if parts[0] in operators:
                op = parts.pop(0)
                value = {'$' + op: value}

            key = '.'.join(parts)
            try:
                field_name, value = self._check_valid_field_name_to_project(
                    key, value)
            except ValueError as e:
                raise e

            cleaned_fields.append((field_name, value))

        fields = sorted(cleaned_fields, key=itemgetter(1))
        for value, group in groupby(fields, lambda x: x[1]):
            fields = [field for field, value in group]
            self._loaded_fields += QueryFieldList(fields,
                                                  value=value,
                                                  _only_called=_only_called)

        return self
Пример #7
0
    def test_default_query_field_list(self):
        query = QueryFieldList()

        expect(query).not_to_be_null()
        expect(query.value).to_equal(QueryFieldList.ONLY)
        expect(query.__nonzero__()).not_to_be_true()
        expect(query.__bool__()).not_to_be_true()
        expect(bool(query)).not_to_be_true()
Пример #8
0
 def __init__(self, klass):
     self.__klass__ = klass
     self._filters = {}
     self._limit = None
     self._skip = None
     self._order_fields = []
     self._loaded_fields = QueryFieldList()
     self._reference_loaded_fields = {}
Пример #9
0
    def test_only_query_field_list(self):
        query = QueryFieldList(['name', 'email'], value=QueryFieldList.ONLY)

        expect(bool(query)).to_be_true()
        expect(query.as_dict()).to_be_like({'name': 1, 'email': 1})
        expect(query.to_query(User)).to_be_like({
            'name': 1,
            'email_address': 1
        })

        query.reset()
        expect(query.as_dict()).to_be_like({})
Пример #10
0
    def test_exclude_query_field_list(self):
        query = QueryFieldList(fields=['name.last', 'email'],
                               value=QueryFieldList.EXCLUDE)

        expect(bool(query)).to_be_true()
        expect(query.as_dict()).to_be_like({'name.last': 0, 'email': 0})
        expect(query.to_query(User)).to_be_like({
            'name.last_name': 0,
            'email_address': 0
        })

        query.reset()
        expect(query.as_dict()).to_be_like({})
Пример #11
0
    def all_fields(self):
        """Include all fields.

        Reset all previously calls of `.only()` or `.exclude().`

        Usage::

            # this will load 'comments' too
            BlogPost.objects.exclude("comments").all_fields().get(...)
        """
        self._loaded_fields = QueryFieldList(
            always_include=self._loaded_fields.always_include)

        return self
Пример #12
0
    def __init__(self, klass):
        if klass.__abstract__ is True:
            raise Exception(
                'Abstract model \'{}\' could not be used for retrieving data'.
                format(klass.__name__))
        self.__klass__ = klass
        self._filters = None
        self._limit = None
        self._skip = None
        self._order_fields = []
        self._loaded_fields = QueryFieldList()
        self._reference_loaded_fields = {}

        if klass.__inherit__ is True:
            child_classes = [
                klass.__hierarchy__,
            ]
            child_classes.extend([
                child_class.__hierarchy__
                for child_class in klass.__child_classes__
            ])
            self._filters = Q({'_cls': {'$in': child_classes}})
Пример #13
0
    def test_union_of_queries_when_only_or_exclude_called(self):
        query1 = QueryFieldList(fields=['name.last', 'email'],
                                value=QueryFieldList.ONLY,
                                _only_called=True)
        query2 = QueryFieldList(fields=['name.first'],
                                value=QueryFieldList.ONLY,
                                _only_called=True)
        query3 = QueryFieldList(fields=['email'], value=QueryFieldList.EXCLUDE)
        query = query1 + query2

        expect(query.as_dict()).to_be_like({
            'name.last': 1,
            'email': 1,
            'name.first': 1
        })

        query = query + query3

        expect(query.as_dict()).to_be_like({'name.last': 1, 'name.first': 1})

        # try again exclude 'email' that is not in the fields now
        query = query + QueryFieldList(['email'], value=QueryFieldList.EXCLUDE)

        expect(query.as_dict()).to_be_like({'name.last': 1, 'name.first': 1})

        # the same but exclude first now
        query = QueryFieldList(['email'], value=QueryFieldList.EXCLUDE) + query

        expect(query.as_dict()).to_be_like({'name.last': 1, 'name.first': 1})

        # exclude first field present in fields
        query = (QueryFieldList(['name.last'], value=QueryFieldList.EXCLUDE) +
                 query)

        expect(query.as_dict()).to_be_like({'name.first': 1})

        # exclude works only with full names not with prefixes
        query = (QueryFieldList(['name'], value=QueryFieldList.EXCLUDE) +
                 query)

        expect(query.as_dict()).to_be_like({'name.first': 1})
Пример #14
0
    def fields(self, _only_called=False, **kwargs):
        """Manipulate how you load this document's fields.

        Used by `.only()` and `.exclude()` to manipulate which fields to
        retrieve. Fields also allows for a greater level of control
        for example:

        Retrieving a Subrange of Array Elements:

        You can use the `$slice` operator to retrieve a subrange of elements in
        an array. For example to get the first 5 comments::

            BlogPost.objects.fields(slice__comments=5).get(...)

        or 5 comments after skipping 10 comments::

            BlogPost.objects.fields(slice__comments=(10, 5)).get(...)

        or you can also use negative values, for example skip 10 comment from
        the end and retrieve 5 comments forward::

            BlogPost.objects.fields(slice__comments=(-10, 5)).get(...)

        Besides slice, it is possible to include or exclude fields
        (but it is strongly recommended to use `.only()` and `.exclude()`
        methods instead)::

            BlogPost.objects.fields(
                slice__comments=5,
                _id=QueryFieldList.EXCLUDE,
                title=QueryFieldList.ONLY
            ).get(...)

        :param kwargs: A dictionary identifying what to include
        """

        # Check for an operator and transform to mongo-style if there is one
        operators = ["slice"]
        cleaned_fields = []
        for key, value in kwargs.items():
            parts = key.split('__')
            if parts[0] in operators:
                op = parts.pop(0)
                value = {'$' + op: value}

            key = '.'.join(parts)
            try:
                field_name, value = self._check_valid_field_name_to_project(
                    key, value)
            except ValueError as e:
                raise e

            cleaned_fields.append((field_name, value))

        # divide fields on groups by their values
        # (ONLY group, EXCLUDE group etc.) and add them to _loaded_fields
        # as an appropriate QueryFieldList
        fields = sorted(cleaned_fields, key=operator.itemgetter(1))
        for value, group in itertools.groupby(fields, lambda x: x[1]):
            fields = [field for field, value in group]
            self._loaded_fields += QueryFieldList(fields,
                                                  value=value,
                                                  _only_called=_only_called)

        return self
Пример #15
0
    def all_fields(self):
        self._loaded_fields = QueryFieldList(
            always_include=self._loaded_fields.always_include)

        return self
Пример #16
0
    def test_slice_query_field_list(self):
        query = QueryFieldList(['numbers'],
                               value={'$slice': 10},
                               _only_called=False)

        expect(query.as_dict()).to_be_like({'numbers': {'$slice': 10}})
Пример #17
0
    def test_slice_and_always_include(self):
        query = (QueryFieldList(['numbers'], always_include=['numbers']) +
                 QueryFieldList(
                     ['numbers'], value={'$slice': 10}, _only_called=False))

        expect(query.as_dict()).to_be_like({'numbers': {'$slice': 10}})
Пример #18
0
    def test_not_only_called_projection(self):
        query = (QueryFieldList() + QueryFieldList(
            ['name'], value=QueryFieldList.ONLY, _only_called=False))

        expect(query.as_dict()).to_be_like({'name': 1})
Пример #19
0
    def test_wrong_value(self):
        query = (QueryFieldList(
            ['name'], value=QueryFieldList.ONLY, _only_called=False) +
                 QueryFieldList(['name'], value='Wrong', _only_called=False))

        expect(query.as_dict()).to_be_like({'name': 1})