Flask查询以及分页

Flask查询以及分页

以动物类做例子
下面创建动物的表

class Animal(db.Model):
    id = db.Column(db.INTEGER, primary_key=True, autoincrement=True)
    a_name = db.Column(db.String(32))
    a_age = db.Column(db.Integer, default=1)

    def save(self):
        db.session.add(self)
        db.session.commit()

下面定义了一个save方法
使我们在定义完对象之后,可以直接调用save方法去存储对象
django中存储对象的时候就是对象.save(),这里就是把flask中添加对象并且提交封装成了save()函数,使我们去调用save函数从而添加并且提交对象

路由:

@app.route('/add_animal/')

flask中路由跟django中的路由有一点不同,flask中路由以装饰器的形式直接写在视图函数上面,而django是从urls文件中单独去写路由,各有利弊。前者比较直观在那个视图函数上方就是那个的路由,不容易搞混,因为可能一个app路由有很多个,但是不利于查找,反而第二种方法,把路由统一存在一个urls文件中,这样方便管理,查找起来也不是很麻烦。

视图函数:

def add_animal():
    name = request.args.get("name")
    age = request.args.get("age")
    animal = Animal()
    animal.a_name = name
    animal.a_age = age
    animal.save()
    return "动物添加成功"

flask中的视图函数跟django中的视图函数没什么不同。不同的点就是django中request.GET.get(),这里就是request.args.get()。

下面是查询:

animals = Animal.query.all()
animals = Animal.query.filter(Animal.a_age <= 3)
animals = Animal.query.filter(Animal.a_age.__le__(3))
animals = Animal.query.filter(Animal.a_name.contains("小"))
animals = Animal.query.filter(Animal.a_age.in_([1,2,3,4,5,6,7,8,18]))
#limit 和 offset不区分顺序,一定先执行 offset,后执行 limit   order_by 必须在limit和offset之前去调用
animals = Animal.query.order_by(text("-a_age")).limit(3)
    # flask 中的所有配置文件
    print(current_app.config)
    for key in current_app.config:
        print(key, current_app.config.get(key))
    return render_template("Animals.html", animals=animals)

通过affset和limit来分页

#分页   每一页有多少  第几页
per_page = int(request.args.get("per_page") or 3)
page = int(request.args.get("page") or 1)

animals = Animal.query.limit(per_page).offset((page-1) * per_page)

使用flask自带的pagination去写分页的视图函数与路由:

@app.route('/animals/')
def animals():
    # pagination = Animal.query.filter(or_(Animal.a_age.__gt__(18), Animal.a_age.__lt__(5))).paginate()
    pagination = Animal.query.filter(and_(Animal.a_age.__lt__(18), Animal.a_age.__gt__(5))).paginate()
    return render_template("animal_list.html", pagination=pagination)

使用bootstrap以及flask中自带的pagination在html中写出漂亮的分页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>动物列表</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
          integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <!-- 可选的 Bootstrap 主题文件(一般不用引入) -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap-theme.min.css"
          integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
            integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
            crossorigin="anonymous"></script>
</head>
<body>

<ul>
    {% for item in pagination.items %}
        <li>{{ item.a_name }}:{{ item.a_age }}</li>
    {% endfor %}

</ul>
<nav aria-label="Page navigation">
    <ul class="pagination">
        {% if pagination.has_prev %}
            <li>
                <a href="/animals/?per_page=3&page={{ pagination.prev_num }}" aria-label="Previous">
                    <span aria-hidden="true">&laquo;</span>
                </a>
            </li>
        {% else %}
            <li class="disabled">
                <a href="#" aria-label="Previous">
                    <span aria-hidden="true">&laquo;</span>
                </a>
            </li>
        {% endif %}
        {%- for page in pagination.iter_pages() %}
            {% if page %}
                {% if page != pagination.page %}
                    <li><a href="/animals/?per_page=3&page={{ page }}">{{ page }}</a></li>
                {% else %}
                    <li class="active"><a>{{ page }}</a></li>
                {% endif %}
            {% else %}
                <span class=ellipsis></span>
            {% endif %}
        {%- endfor %}
        {% if pagination.has_next %}
            <li>
                <a href="/animals/?per_page=3&page={{ pagination.next_num }}" aria-label="Next">
                    <span aria-hidden="true">&raquo;</span>
                </a>
            </li>
        {% else %}
            <li class="disabled">
                <a href="#" aria-label="Next">
                    <span aria-hidden="true">&raquo;</span>
                </a>
            </li>
        {% endif %}
    </ul>
</nav>
</body>
</html>

钩子函数也是flask中间件:

  • Django中的中间件
  • AOP(面向切面编程)
  • before_request
  • after_request
@app.route('/animals/')
def animals():
    print("处理中")
    pagination = Animal.query.filter(and_(Animal.a_age.__lt__(18), Animal.a_age.__gt__(5))).paginate()
    return render_template("animal_list.html", pagination=pagination)
    
@app.before_request
def before():
    print("请求前")

@app.after_request
def after(resp):
    print("请求结束")
    return resp

@app.before_request是请求之前的路由
@app.after_request是请求之后的路由,返回response

在创建数据库表的时候我们会有一类东西可能会涉及到继承比如:

class Dog(db.Model):
    __abstract__ = True
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    d_name = db.Column(db.String(16))


class BlackDog(Dog):

    b_price = db.Column(db.Float, default=1)


class WhiteDog(Dog):

    w_price = db.Column(db.Float, default=2)

如果不加 abstract 抽象属性的话只会产生一个表,那样创建的对象会有很多的空值,这样全部都会成为费数据
给父模型加上下面的属性:
abstract = True
抽象的模型不会产生表映射
子模型会获取父表中的所有字段

Flask四大内置对象

  • request
  • session
  • g
    • 全局对象
    • 可以用来传递数据
    • 做数据载体,容器
  • config (app)
    • 配置
    • 整个app的配置
      • key-value
发布了58 篇原创文章 · 获赞 0 · 访问量 506

猜你喜欢

转载自blog.csdn.net/qq_41170489/article/details/103617576