Flask - запрос нескольких столбцов базы данных из одного URL с несколькими параметрами, используя request.arg - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь создать сетку, которую можно отфильтровать по нескольким параметрам в URL-адресе, используя request.arg

Я нашел это решение , которое, похоже, на месте, но я получаю следующую ошибку

Файл "/Users/tobias/Dropbox/Repos/app/views.py", строка 208, в filter_query op = getattr (operator, _filter.operator) AttributeError: модуль 'operator' не имеет атрибута 'fred'

Что я делаю не так?

URL: http://127.0.0.1: 5000 / books? filter = author, fred, тобиас

class Books(db.Model):
    __tablename__ = "book"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(255), nullable=False)
    author = db.Column(db.String(255), nullable=False)
    supplier = db.Column(db.String(255))
    published = db.Column(db.Date, nullable=False)

Книжный стол:

# id, title, author, supplier, published
'1', 'papillon', 'tobias', 'ikea', '2020-12-01'
'2', 'park', 'fred', 'vw', '2020-12-02'
class QueryValidationError(Exception):
    """ We can handle specific exceptions and 
        return a http response with flask """
    pass

class Filter:
    #supported_operators = ("companyName", "country", "kitemana", "2XS", "Netherlands", "ge")
    supported_operators = ("Netherlands","companyName","eq","tobias", "vw", "fred")

    def __init__(self, column, operator, value):
        self.column = column
        self.operator = operator
        self.value = value
        self.validate()

    def validate(self):
        if self.operator not in self.supported_operators:
            raise QueryValidationError(
                f"operator `{self.operator}` is not one of supported "
                f"operators `{self.supported_operators}`"
            )


def create_filters(filters):
    filters_processed = []
    if filters is None:
        # No filters given
        return filters_processed
    elif isinstance(filters, str):
        # if only one filter given
        filter_split = filters.split(",")
        filters_processed.append(
            Filter(*filter_split)
        )
    elif isinstance(filters, list):
        # if more than one filter given
        try:
            filters_processed = [Filter(*_filter.split(",")) for _filter in filters]
        except Exception:
            raise QueryValidationError("Filter query invalid")
    else:
        # Programer error
        raise TypeError(
            f"filters expected to be `str` or list "
            f"but was of type `{type(filters)}`"
        )

    return filters_processed


def filter_query(filters, query, model):
    for _filter in filters:
        # get our operator
        op = getattr(operator, _filter.operator)
        # get the column to filter on
        column = getattr(model, _filter.column)
        # value to filter for
        value = _filter.value

        # build up a query by adding multiple filters
        query = query.filter(op(column, value))

    return query


@app.errorhandler(QueryValidationError)
def handle_query_validation_error(err):
    return jsonify(dict(
        errors=[dict(
            title="Invalid filer",
            #details=err.msg,
            details=[str(x) for x in err.args],
            status="400")
        ]
    )), 400



@app.route("/books", methods=["GET"])
def all_books():
    args = request.args
    filters = create_filters(args.get("filter"))
    query = Books.query
    query = filter_query(filters, query, Books)

    result = []
    for book in query.all():
        result.append(dict(
            id=book.id,
            title=book.title,
            author=book.author,
            supplier=book.supplier,
            published=str(book.published)
        ))

    return jsonify(result), 200

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...