zoukankan      html  css  js  c++  java
  • Flask复习(配置数据库/ORM操作/使用原生SQL查询/HTTP请求(get/post)/详解url)

    一、配置数据库信息

    config.py数据库信息配置

    #设置连接数据库路径
    DB_URI = "mysql+pymysql://root:root@127.0.0.1:3306/bbs?charset=utf8"      #msyql+pymysql://用户名:密码@数据库连接地址:端口号/数据库名
    
    #SQLALCHEMY_DATABASE_URI加载配置好的URI
    SQLALCHEMY_DATABASE_URI = DB_URI
    #决定是否追踪对象的修改,一般设置False
    SQLALCHEMY_TRACK_MODIFICATIONS =False

    exts.py为了解决循环调用,单独把SQLAlchemy独立成在一个文件中

    from flask_sqlalchemy import SQLAlchemy     #导入模块
    db = SQLAlchemy()

    Models.py模型类,用来生成数据库表

    from exts import db     #导入db模块,设置字段
    
    class UserInfo(db.Model):
        #指定表名,没有就用类名做表名
        __tablename__='user_info'
        #id设置为主键并且自动增长
        id=db.Column(db.Integer,primary_key=True,autoincrement=True)
        username=db.Column(db.String,nullable=False)

    数据迁移

     使用flask_script和flask_migrate

    二、ORM操作(增删改查)     https://blog.csdn.net/weixin_42750983/article/details/82431257

    1.增加数据    (flask中修改数据后需要添加事务和提交事务)

    #实例化模型类作为一条记录
    document = Post(author_id=user_id, title=request.form['title'], body=request.form['corpus'], created=d_time,has_edited=True)     #将值对应字段传入
    
    db.session.add(document)    #把新创建的记录添加到数据库会话
    db.session.commit()        #提交到数据库会话
    
    #添加多条记录使用add_all(),也可以传入单条记录,也可以传入一个列表:[document1,document2,document3]
    db.session.add_all([document1,document2,document3])

    2.查询数据

    常用过滤器(指查询条件,如果没有查询条件下面这些用不到,直接使用查询执行器)

    filter(条件)     返回符合该条件的查询集,BaseQuery对象        Book.query.filter(Book.id==1)
    filter_by()     和filter查询一样,只是括号内的条件写法不一样   Book.query.filter_by(id=1)
    limit           使用指定的值限定原查询返回的结果
    offset()
    order_by()     根据字段进行排序,默认是正序,返回新查询集,desc可以反序   Book.query.order_by(Book.id)     Book.query.order_by(Book.id.desc)
    group_by()     根据字段进行分组,返回新查询集合

    常用查询执行器 

    all()       以列表形式返回查询的所有结果     Book.query.filter(Book.id==1).all()
    first()     返回查询的第一个结果,如果未查到,返回None   Book.query.filter(Book.id==1).first()
    get()       返回指定主键对应的行       Book.query.get(1)   #写的是主键值
    count()     返回查询结果的数量         Book.query.count()
    paginate()  返回一个Paginate对象,参数一:第几页,参数二:每页个数,参数3:如果没有该页数返回False         Book.query.paginate(2,3,False)

    两种查询写法

    1.基于实体类来查询                #模型类.query.过滤方法函数()
    2.根据db.session.query() #db.session.query(查询的数据).过滤方法函数()

    db.session.query(模型类) 等价于 模型类.query db.session.query()功能更强大,可以进行多表查询

     示例     参考链接:https://www.cnblogs.com/lovershowtime/p/11756891.html

    all():查询全部的数据,其结果是一个列表,每一个元素都是一个对象  
               students = Student.query.all()
    order_by():查询按序排列
    get(): 直接写查询条件  User.query.get(1)  #用主键查询用户
    
    过滤查询:
        1.filter   查询结果是<class 'flask_sqlalchemy.BaseQuery'>,打印出来是SQL语句
        studnets = Student.query.filter(Student.id==1)
        2.filter_by   查询结果和filter一样
        students = Student.query.filter_by(id=1)
        3.原生sql查询id=1的信息
        sql = 'select * from student where id=1;'    
        students = db.session.execute(sql)

    between 在什么之间

    aa=session.query(Users).filter(Users.id.between(4, 7), Users.name == '李四').all()

    like 通配符

    ret1 = db.session.query(Users).filter(Users.name.like('李%')).all()

    切片

    result = db.session.query(Users)[1:3]     #[<Users 2>, <Users 3>]  

    order_by(排序)

    ret1 = session.query(Users).order_by(Users.name.desc()).all()     #desc升序   asc是降序

    group_by (分组)

    from sqlalchemy.sql import func   # 导入 func,func 中有聚合函数
    
    ret = db.session.query(
            Users.dep_id,
            func.count(Users.id),
    ).group_by(Users.dep_id).all()

    distinct(去重)

    from sqlalchemy import distinct    #导入distinct
    
    #去重后的标签名
    labels=dbS.session.query(distinct(Label.label_name)).all()
    #去重后的标签数量
    label_distinct=dbS.session.query(func.count(distinct(Label.label_name))).all()

    limit(可以限制每次查询数量)

    #查询10条
    post=db.session.query(Post).limit(10).all()

    offset(限制查找数据的时候过滤掉前面多少条)

    post=db.session.query(Post).offset(10).limit(10).all()

    slice(切片)

    post=db.session.query(Post).slice(10,20).all()

    3.修改数据

    思路:获取到需要修改的对象,通过对象.属性的方式将属性重新赋值,然后使用commit提交事务

    写法1:查询出需要修改对象,通过对象.属性方式修改

    students = Student.query.filter_by(s_id=3).first()
    students.s_name = '哈哈'
    db.session.commit()

    写法2:通过update修改

    Student.query.filter_by(s_id=3).update({'s_name':'娃哈哈'})
    db.session.commit()

    4.删除数据

    思路:查询出需要删除的对象,调用db.session.delete(记录对象)实现,然后db.session.commit()提交会话

    写法1:

    students = Student.query.filter_by(s_id=2).first()
    db.session.delete(students)
    db.session.commit()

    写法2:

    students = Student.query.filter_by(s_id=1).all()
    db.session.delete(students[0])
    db.session.commit()

    数据库查询使用原生sql:excute()  ******

    data = db.session.excute('SELECT id FROM user WHERE username = ?', (username,)) 使用?占位符,后面的元组参数可以代替
    data.fetchone()查询返回一个记录行。如果没有查询结果,则返回None。还有fetchall(),返回所有结果的列表,列表里面的元素是sql类型

    三、HTTP请求

    GET提交的数据会放在URL中,以?分割URL的传输数据
    POST方法是把提交的数据放在HTTP包的请求体中

    从flask中导入request对象

    from flask import request

    请求相关信息

    request.method          提交的方法
    request.args            get请求提及的数据
    request.form            post请求提交的数据
    request.values          post和get提交的数据总和
    request.cookies         客户端所带的cookie
    request.headers         请求头
    request.path            不带域名,请求路径
    request.full_path       不带域名,带参数的请求路径
    request.script_root  
    request.url             带域名带参数的请求路径
    request.base_url        带域名请求路径
    request.url_root        域名
    request.host_url        域名
    request.host            127.0.0.1:500
    request.files

    Flask关于request一些方法

    一、post 请求 (Content-Type: application/json)
    1.data = request.get_data()     #一般使用这个
    可以获取未经处理过的原始数据而不管内容类型,如果数据格式是json的,则取得的是json字符串,排序和请求参数一致
    2.data = request.get_json()
    将请求参数做了处理,得到的是字典格式的,因此排序会打乱依据字典排序规则
    3.data = request.data
    可以获取未经处理过的原始数据,如果数据格式是json的,则取得的是json字符串,排序和请求参数一致
    4.data = request.json
    
    二、get请求
    1.request.args.get("key")可以获取单个的值
    2.request.args可以获取get请求的所有参数返回值是ImmutableMultiDict类型
    3.requestValues.to_dict()将获得的参数转换为字典

    1.GET请求使用request获取url中数据

    访问:http://127.0.0.1:5000/name?page=1

    使用request的属性获取url
    request.path                     /name
    request.full_path              /name?page=1
    request.values['page']         1        #获取参数page的值
    request.args.get('page')       1        #和上面一样也是获取参数page的值

    代码示例

    @app.route('/name',methods=['POST','GET'])
    def hello_world():
        print(request.values['page'])     #1      #获取路由传递参数
        print(request.args.get('page'))   #1
    
        return 'Hello World!'

    2.POST请求    post请求:会给服务器提交一些数据

    先了解一下render_template:会去flask根目录下的template里面寻找文件,所以给的路径是相对路径

    代码示例:将数据search_result和title传递到blog/index.html中

    return render_template("blog/index.html", search=search_result, title=title)

    request.form是专门用来针对接收表单数据的

    request.form.get('username')     #form表单设置的name值username
    request.form.get('password')     #form表单设置的name值password

    代码示例

    # 获取get的请求参数
    if request.method == 'GET':
        name = request.args.get('name')  # 从get参数里获取名为name的参数
        password = request.args.get('password')  # 从get参数里获取名为name的参数
        return '这是GET方法,请求获取的参数'
    # 获取post的请求参数(表单)
    if request.method == 'POST':
        # post方法多是需要修改数据库,并且都是表单提交上来的所以用form
        name = request.form.get('name')  # 从get参数里获取名为name的参数
        password = request.form.get('password')  # 从get参数里获取名为name的参数
        # 这里也可以操作把表单提交上来的数据存到数据库里,然后返回json数据
        return '这是POST方法,请求的'

    四、详解url

    1. 动态路由传参

    @app.route('/student_list/<student_id>/')    #注意写<>
    def student_list(student_id):                #这个和前面request获取路径上参数用法是不一样的
        return '学生{}号的信息'.format(student_id)

    动态路由的过滤

    @app.route('/student_list/<int:student_id>/')    #限定student_id必须是整数类型
    def student_list(student_id):                
        return '学生{}号的信息'.format(student_id)

    默认转换器

    DEFAULT_CONVERTERS = {
        'default':          UnicodeConverter,
        'string':           UnicodeConverter,   #默认的数据类型(字符串)
        'any':              AnyConverter,
        'path':             PathConverter,
        'int':              IntegerConverter,   #数字类型
        'float':            FloatConverter,
        'uuid':             UUIDConverter,
    }

    2.查询字符串传参(就是路由传参)

    www.baidu.com/s?wd=python&ad=flask     这个?后的key=value便是查询字符串传参
    通过request.args属性根据字符串中的key取出字符串的value

    例如:https://127.0.0.1:5000/studet_name?name=xxx&age=xx

    from flask import Flask,request
    
    @app.route('/student_name/')
    def school_name_list():
        name=request.args.get('name')         #获取路径中key=name的值,使用request.values['name']也可以
        age=request.args.get('age')           #获取路径中key=age的值
         
        return "学生的姓名为{},年龄为{}".format(name,age)

    3.url_for()的使用      

     url_for()的原理:利用视图函数名字一般不会改变的特性,利用视图函数的名字去动态精准的获取url

    url_for('视图函数名字')    #输出该视图函数url

    例子:

    from flask import Flask,url_for
    
    app = Flask(__name__)
    app.config.update(DEBUG=True)
    
    @app.route('/')
    def demo1():
        print(url_for("book"))        #/book_list/   # 注意这个引用的是视图函数的名字 字符串格式,输出是url地址
        print(type(url_for("book")))  # <class 'str'>
    
        return url_for("book")        #/book_list/
    
    @app.route('/book_list/')
    def book():
    
        return 'flask_book'
    
    if __name__ ==  "__main__":
        app.run()

    url_for如何处理动态路由的视图函数

    如果想获取动态路由,必须以关键字实参的形式为动态的path部分赋值,注意动态的path部分必须被赋值

    @app.route('/demo2/')
    def demo2():  
        student_url = url_for('student', id=5, name='mark',age=18)   #id是动态path的key必须赋值,name和age作为查询字符串传入                                                            # name 将作为查询字符串传入
        print(student_url)      #/student/5/?name=mark&age=18
    
        return student_url
    
    @app.route('/student/<int:id>/')
    def student(id):
        return 'student {}'.format(id)

    url_for如何为url添加查询字符串

    在路径后面拼出来查询字符串,以关键字实参的形式放到url_for()里面作为参数,会自动拼成路径

    @app.route('/demo3/')
    def demo3():
        school_url = url_for('school', school_level='high', name='college') 
        # 具体要拼接的查询参数 以关键字实参的形式写在url_for里
        print(school_url)         #/school/?school_level=high&name=college
    
        return school_url
    
    @app.route('/school/')
    def school():
    
        return 'school message'

    注意:url_for()不仅可以在视图函数中使用也可以在前端使用

    前端使用方法:
    href={{ url_for('blog.analysis',id =post['id'])}}       #和在视图函数中一样使用url_for('视图函数名'),也可以设置参数
  • 相关阅读:
    关于欧拉函数
    JavaWeb技术
    jQuery介绍
    Spring之事务管理
    Hibernate课堂笔记
    JSON简介
    Ajax简介
    Java代码生成图片验证码
    JAVA学习笔记——ClassLoader中getResource方法的路径参数
    JAVA OOP学习笔记——多态(polymorphism)
  • 原文地址:https://www.cnblogs.com/wangcuican/p/13089953.html
Copyright © 2011-2022 走看看