Exemple #1
0
    def select_related(self, *args):
        select_related = {'action': 'db__select_related', 'fields': []}
        for arg in args:
            # fr the time been we overlook the after the '__'
            if '__' in arg:
                arg = arg.split('__')[0]
            if not hasattr(self.model, arg):
                raise QuerysetError('{} is not a {} attribute.'.format(
                    arg, self.model.__name__))
            if not isinstance(getattr(self.model, arg), ForeignKey):
                raise QuerysetError(
                    '{} is not a ForeignKey Field for {}.'.format(
                        arg, self.model.__name__))
            model = self.orm.get_model(getattr(self.model, arg).foreign_key)

            right_table = model.table_name or model.__name__.lower()
            left_table = self.model.table_name or self.model.__name__.lower()

            fields_formatter = ', '.join([
                '{right_table}.{field} AS {right_table}€$$€{field}'.format(
                    right_table=right_table, field=field)
                for field in model.get_db_columns()
            ])
            select_related['fields'].append({
                'right_table': right_table,
                'left_table': left_table,
                'foreign_field': arg,
                'model_db_pk': model.db_pk,
                'fields_formatter': fields_formatter,
                'orm_fieldname': arg,
            })
        queryset = self._copy_me()
        queryset.query.append(select_related)

        return queryset
Exemple #2
0
    def select_related(self, *args):
        select_related = {"action": "db__select_related", "fields": []}
        for arg in args:
            # fr the time been we overlook the after the '__'
            if "__" in arg:
                arg = arg.split("__")[0]
            if not hasattr(self.model, arg):
                raise QuerysetError("{} is not a {} attribute.".format(
                    arg, self.model.__name__))
            if not isinstance(getattr(self.model, arg), ForeignKey):
                raise QuerysetError(
                    "{} is not a ForeignKey Field for {}.".format(
                        arg, self.model.__name__))
            model = self.orm.get_model(getattr(self.model, arg).foreign_key)

            right_table = model.table_name or model.__name__.lower()
            left_table = self.model.table_name or self.model.__name__.lower()

            fields_formatter = ", ".join([
                "{right_table}.{field} AS {right_table}€$$€{field}".format(
                    right_table=right_table, field=field)
                for field in model.get_db_columns()
            ])
            select_related["fields"].append({
                "right_table": right_table,
                "left_table": left_table,
                "foreign_field": arg,
                "model_db_pk": model.db_pk,
                "fields_formatter": fields_formatter,
                "orm_fieldname": arg,
            })
        queryset = self._copy_me()
        queryset.query.append(select_related)

        return queryset
Exemple #3
0
    async def calculate(self, field_name, operation):
        if hasattr(self.model, field_name):
            field = getattr(self.model, field_name)
        else:
            raise QuerysetError('{} wrong field name for model {}'.format(
                field_name, self.model.__name__))
        if not isinstance(field, NumberField):
            raise QuerysetError('{} is not a numeric field'.format(field_name))

        query = self.query_copy()
        query[0]['select'] = '{}({})'.format(operation, field_name)

        resp = await self.db_request(query)
        for v in resp.values():
            return v
Exemple #4
0
    async def __getitem__(self, key):
        if isinstance(key, slice):
            # control the keys values
            if key.start is not None and key.start < 0:
                raise QuerysetError('Negative indices are not allowed')
            if key.stop is not None and key.stop < 0:
                raise QuerysetError('Negative indices are not allowed')
            if key.step is not None:
                raise QuerysetError('Step on Queryset is not allowed')

            # asign forward and stop to the modelmanager and return it
            self.forward = key.start
            self.stop = key.stop
            if key.start is None:
                self.forward = 0
            return self

        elif isinstance(key, int):
            # if its an int, the developer wants the object directly
            if key < 0:
                raise QuerysetError('Negative indices are not allowed')

            conn = await self.db_manager.get_conn()

            cursor = self._cursor
            if not cursor:
                query = self.db_manager.construct_query(deepcopy(self.query))
                cursor = Cursor(
                    conn,
                    query[0],
                    values=query[1],
                    forward=key,
                )

            async for res in cursor:
                return self.modelconstructor(res)
            raise IndexError('That {} index does not exist'.format(
                self.model.__name__))

        else:
            raise TypeError("Invalid argument type.")
Exemple #5
0
    def only(self, *args):
        # retrieves from the database only the attrs requested
        # all the rest come as None
        for arg in args:
            if not hasattr(self.model, arg):
                raise QuerysetError('{} is not a correct field for {}'.format(
                    arg, self.model.__name__))

        queryset = self.queryset()
        queryset.query = self.query_copy()
        queryset.query[0]['select'] = ','.join(args)

        return queryset
Exemple #6
0
    def order_by(self, *args):
        # retrieves from the database only the attrs requested
        # all the rest come as None
        final_args = []
        for arg in args:
            if arg[0] == '-':
                arg = arg[1:]
                final_args.append('-' + arg)
            else:
                final_args.append(arg)

            if not hasattr(self.model, arg):
                raise QuerysetError('{} is not a correct field for {}'.format(
                    arg, self.model.__name__))

        queryset = self.queryset()
        queryset.query = self.query_copy()
        queryset.query[0]['ordering'] = final_args

        return queryset
Exemple #7
0
    def calc_filters(self, kwargs, exclude):
        # recompose the filters
        bool_string = exclude and 'NOT ' or ''
        filters = []

        for k, v in kwargs.items():
            # we format the key, the conditional and the value
            operator = '{t_n}.{k} = {v}'
            lookup = None
            if len(k.split('__')) > 1:
                k, lookup = k.split('__')
                operator = LOOKUP_OPERATOR[lookup]

            field = getattr(self.model, k)

            string_lookups = [
                'exact',
                'iexact',
                'contains',
                'icontains',
                'startswith',
                'istartswith',
                'endswith',
                'iendswith',
            ]

            operator_formater = {
                't_n': self.model.table_name or self.model.__name__.lower(),
                'k': field.db_column,
                'v': v
            }
            if operator == '({t_n}.{k}>={min} AND {t_n}.{k}<={max})':
                if not isinstance(v, (tuple, list)):
                    raise QuerysetError(
                        '{} should be list or a tuple'.format(lookup))
                if len(v) != 2:
                    raise QuerysetError(
                        'Not a correct tuple/list definition, should be of size 2'
                    )
                operator_formater.update({
                    'min': field.sanitize_data(v[0]),
                    'max': field.sanitize_data(v[1]),
                })
            elif lookup in string_lookups:
                is_charfield = isinstance(field, CharField)
                # is_othercharfield = issubclass(field, CharField)
                # if not is_charfield or not is_othercharfield:
                if not is_charfield:
                    raise QuerysetError(
                        '{} not allowed in non CharField fields'.format(
                            lookup))
                operator_formater['v'] = field.sanitize_data(v)
            else:
                if isinstance(v, (list, tuple)):
                    # check they are correct items and serialize
                    v = ','.join([
                        "'{}'".format(field.sanitize_data(si)) if isinstance(
                            si, str) else str(si) for si in v
                    ])
                elif v is None:
                    v = field.sanitize_data(v)[1:-1]
                    operator = operator.replace('=', 'IS')
                elif isinstance(v, datetime.datetime) or isinstance(
                        field, (CharField)):
                    v = "'{}'".format(v)
                else:
                    v = field.sanitize_data(v)
                operator_formater['v'] = v

            filters.append(bool_string + operator.format(**operator_formater))

        return filters
Exemple #8
0
    def calc_filters(self, kwargs, exclude):
        # recompose the filters
        bool_string = exclude and "NOT " or ""
        filters = []

        for k, v in kwargs.items():
            # we format the key, the conditional and the value
            operator = "{t_n}.{k} = {v}"
            lookup = None
            if len(k.split("__")) > 1:
                k, lookup = k.split("__")
                operator = LOOKUP_OPERATOR[lookup]

            field = getattr(self.model, k)

            string_lookups = [
                "exact",
                "iexact",
                "contains",
                "icontains",
                "startswith",
                "istartswith",
                "endswith",
                "iendswith",
            ]
            operator_formater = {
                "t_n": self.model.table_name or self.model.__name__.lower(),
                "k": field.db_column,
                "v": v,
            }
            if operator == "({t_n}.{k}>={min} AND {t_n}.{k}<={max})":
                if not isinstance(v, (tuple, list)):
                    raise QuerysetError(
                        "{} should be list or a tuple".format(lookup))
                if len(v) != 2:
                    raise QuerysetError(
                        "Not a correct tuple/list definition, should be of size 2"
                    )
                operator_formater.update({
                    "min": field.sanitize_data(v[0]),
                    "max": field.sanitize_data(v[1])
                })
            elif lookup in string_lookups:
                is_charfield = isinstance(field, CharField)
                # is_othercharfield = issubclass(field, CharField)
                # if not is_charfield or not is_othercharfield:
                if not is_charfield:
                    raise QuerysetError(
                        "{} not allowed in non CharField fields".format(
                            lookup))
                operator_formater["v"] = field.sanitize_data(v)
            else:
                if isinstance(v, (list, tuple)):
                    # check they are correct items and serialize
                    v = ",".join([
                        "'{}'".format(field.sanitize_data(si)) if isinstance(
                            si, str) else str(si) for si in v
                    ])
                elif v is None:
                    v = field.sanitize_data(v)[1:-1]
                    operator = operator.replace("=", "IS")
                elif isinstance(
                        v, (datetime.datetime, datetime.date)) or isinstance(
                            field, (CharField)):
                    v = "'{}'".format(v)
                else:
                    v = field.sanitize_data(v)
                operator_formater["v"] = v

            filters.append(bool_string + operator.format(**operator_formater))

        return filters