示例#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 AsyncOrmQuerysetError("{} is not a {} attribute.".format(
                    arg, self.model.__name__))
            if not isinstance(getattr(self.model, arg), ForeignKey):
                raise AsyncOrmQuerysetError(
                    "{} 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
示例#2
0
    async def calculate(self, field_name, operation):
        if hasattr(self.model, field_name):
            field = getattr(self.model, field_name)
        else:
            raise AsyncOrmQuerysetError(
                "{} wrong field name for model {}".format(
                    field_name, self.model.__name__))
        if not isinstance(field, NumberField):
            raise AsyncOrmQuerysetError(
                "{} 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
示例#3
0
    async def __getitem__(self, key):
        if isinstance(key, slice):
            wrong_start_key = key.start is not None and key.start < 0
            wrong_stop_key = key.stop is not None and key.stop < 0
            if wrong_start_key or wrong_stop_key:
                raise AsyncOrmQuerysetError("Negative indices are not allowed")

            if key.step is not None:
                raise AsyncOrmQuerysetError("Step on Queryset is not allowed")

            return self._get_queryset_slice(key)

        elif isinstance(key, int):
            if key < 0:
                raise AsyncOrmQuerysetError("Negative indices are not allowed")

            return await self._get_item(key)

        else:
            raise TypeError("Invalid argument type.")
示例#4
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 AsyncOrmQuerysetError(
                    "{} 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
示例#5
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 AsyncOrmQuerysetError(
                    "{} 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
示例#6
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 AsyncOrmQuerysetError(
                        "{} should be list or a tuple".format(lookup))
                if len(v) != 2:
                    raise AsyncOrmQuerysetError(
                        "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 AsyncOrmQuerysetError(
                        "{} not allowed in non CharField fields".format(
                            lookup))
                operator_formater["v"] = field.sanitize_data(v)
            elif lookup == "in" and isinstance(v, (list, tuple)) and not v:
                # we can skip this case to avoid error with empty array
                raise AsyncOrmEmptyResult
            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