Exemplo n.º 1
0
def model_filter_by_get_params(model: DefaultMeta, query: BaseQuery,
                               args: dict) -> BaseQuery:
    """
    Here is implemented a search and filtering the model by request url params. There are several possible variants of
    search, and, of course, they can be easily combined to attain the necessary result.
    Method received three obligatory parameters: model - sqlalchemy orm model class, query - :class:`BaseQuery` object
    to filtering and args - dict of already parsed url params.
        1. User can look for the model instances by putting columns names directly and their theoretical values, like:
            http://localhost:5000/api/users?username=dima&name=dmytro. Such queries will select only exact matches.
        2. To search without an exact match use `-like` ending after db columns names. It works only if column has type
            :class:`sqlalchemy.sql.sqltypes.String` and gives the result from sql `LIKE` statement. Common url looks
            like: http://localhost:5000/api/users?username-like=ma
        3. To sort an output use 'ordered-by' and 'ordered-by-desc' parameter and specify db column name to order by:
            http://localhost:5000/api/users?name-like=a&ordered-by=username
        4. To restrict the number of results use 'limit' and 'offset' statements together or separately:
            http://localhost:5000/api/users?name-like=a&ordered-by=username&limit=2&offset=3

        A simple use case is below::

            from flask import request
            from app import db
            @route('/')
            def index():
                users = User.query
                users = model_filter_by_get_params(User, users, request.args).all()

    If given params are not valid, they will be ignored.
    The function can pe applied for different models and queries and can be expanded if it is necessary.
    :param model: model base class
    :type model: DefaultMeta
    :param query: not executed query object to filtering
    :type query: BaseQuery
    :param args: url query parameters
    :type args: dict
    :return: not executed filtered query object
    :rtype: BaseQuery
    """
    model_columns = model.__table__.c.keys()
    for key, value in args.items():
        if key == 'ordered-by':
            if value in model_columns:
                query = query.order_by(getattr(model, value))
        elif key == 'ordered-by-desc':
            if value in model_columns:
                query = query.order_by(desc(getattr(model, value)))
        elif key.endswith('-like'):
            attr = key.split('-like')[0]
            if attr in model_columns and isinstance(
                    model.__table__.c.get(attr).type, String):
                query = query.filter(getattr(model, attr).ilike(f'%{value}%'))
        elif key in model_columns:
            query = query.filter(getattr(model, key) == value)
    if 'limit' in args:
        query = query.limit(int(args.get('limit')))
    if 'offset' in args:
        query = query.offset(int(args.get('offset')))
    return query
Exemplo n.º 2
0
 def apply_order(query: BaseQuery, sort_keys: str) -> BaseQuery:
     if sort_keys:
         for key in sort_keys.split(","):
             desc = False
             if key.startswith("-"):
                 key = key[1:]
                 desc = True
             column_attr = getattr(GithubUserInfo, key, None)
             if column_attr is not None:
                 query = (query.order_by(column_attr.desc())
                          if desc else query.order_by(column_attr))
     return query
Exemplo n.º 3
0
def apply_order(model: DefaultMeta, query: BaseQuery) -> BaseQuery:
    sort_keys = request.args.get('sort')
    if sort_keys:
        for key in sort_keys.split(','):
            desc = False
            if key.startswith('-'):
                key = key[1:]
                desc = True
            column_attr = getattr(model, key, None)
            if column_attr is not None:
                query = query.order_by(column_attr.desc()) if desc else query.order_by(column_attr)
    return query
Exemplo n.º 4
0
def apply_order(model: DefaultMeta, query: BaseQuery) -> BaseQuery:
    """
    Functionality of sorting resources, returns sort arguments to query
    (example: sort=-id,last_name).
    """
    sort_keys = request.args.get("sort")
    if sort_keys:
        for key in sort_keys.split(","):
            desc = False
            if key.startswith("-"):
                key = key[1:]
                desc = True
            column_attr = getattr(model, key, None)
            if column_attr is not None:
                query = (query.order_by(column_attr.desc())
                         if desc else query.order_by(column_attr))
    return query
Exemplo n.º 5
0
 def apply_engine_specific_hack(self, query: BaseQuery, page, page_size,
                                order_column) -> BaseQuery:
     # MSSQL exception page/limit must have an order by
     if (page and page_size and not order_column
             and self.session.bind.dialect.name == "mssql"):
         pk_name = self.get_pk_name()
         return query.order_by(pk_name)
     return query
Exemplo n.º 6
0
 def apply_order_by(self, query: BaseQuery, order_column: str,
                    order_direction: str) -> BaseQuery:
     if order_column != "":
         # if Model has custom decorator **renders('<COL_NAME>')**
         # this decorator will add a property to the method named *_col_name*
         if hasattr(self.obj, order_column):
             if hasattr(getattr(self.obj, order_column), "_col_name"):
                 order_column = getattr(self._get_attr(order_column),
                                        "_col_name")
         _order_column = self._get_attr(order_column) or order_column
         if is_column_dotted(order_column):
             query = self._query_join_relation(
                 query, get_column_root_relation(order_column))
         if order_direction == "asc":
             query = query.order_by(asc(_order_column))
         else:
             query = query.order_by(desc(_order_column))
     return query
Exemplo n.º 7
0
def ql_don_hang_all(page=1):
    if not current_user.is_authenticated or current_user.ma_loai_nguoi_dung != 1:
        return redirect(url_for('dang_nhap', next=request.url))
    query = BaseQuery(Hoa_don, dbSession)
    page_filter = query.order_by(desc(Hoa_don.ngay_tao_hoa_don)).paginate(
        page, 10, False)

    tieu_de = 'Tất cả đơn hàng'

    return render_template('Quan_ly/QL_don_hang/QL_don_hang_all.html',
                           page_filter=page_filter,
                           tieu_de=tieu_de)
Exemplo n.º 8
0
def set_sort_order(query: BaseQuery,
                   obj_model: Model,
                   sort_order="asc",
                   sort_by="id",
                   *args,
                   **kwargs) -> BaseQuery:
    if sort_order is not None:
        sort = asc if sort_order == "asc" else desc
    else:
        sort = asc
    # sort = asc if sort_order == "asc" else desc
    column = next((c for c in inspect(obj_model).columns if c.name == sort_by),
                  "id")
    return query.order_by(sort(column))
Exemplo n.º 9
0
def force_pagination(query: BaseQuery, order=None):
    query = query.order_by(order if order is not None else desc('id'))
    page = int(request.values.get('page', 1))
    per_page = int(request.values.get('per_page', FETCH_LIMIT))
    pagination = query.paginate(page, per_page,
                                error_out=False)  # type: Pagination
    return jsonify({
        'rows': [instance.to_json() for instance in pagination.items],
        'max_page':
        pagination.pages,
        'curr_page':
        pagination.page,
        'next_page':
        pagination.next_num,
        'prev_page':
        pagination.prev_num,
    })
Exemplo n.º 10
0
    def _construct_query(
        query: BaseQuery,
        filter: BinaryExpression = None,
        order: BinaryExpression = None,
    ) -> BaseQuery:
        """
        A convenience function to save code space for query generations. Takes filters
        and order_bys and applies them to the query, returning a query ready to be ran.

        :param query:  A query that can be built upon
        :param filter: A SQLAlchemy query filter expression
        :param order:  A SQLAlchemy query order_by expression

        :return:       A Flask-SQLAlchemy ``BaseQuery``
        """
        if filter is not None:
            query = query.filter(filter)
        if order is not None:
            query = query.order_by(order)
        return query
 def get_geonames_sorted(geonames: BaseQuery) -> BaseQuery:
     return geonames.order_by(GeoName.population.desc())