zoukankan      html  css  js  c++  java
  • SQLAlchemy+Flask-RESTful使用(四)

    前言

    顺利出到4啦,其实学习过程中发现了不少错误,不过有些实在是没啥代表性.

    最近买了两本小程序和安卓方面的书,其实从初中开始,想搞编程的目的就是写些安卓软件.

    现在看来不太可能了.拿来当当兴趣爱好还是没问题的

    这几天不是没更新,是在前面的章节里增加/勘误

    变更记录

    # 19.4.15  起笔

    # 19.4.15  增加 Flask-RESTful 获取url传参

    # 19.4.15  增加 Flask-RESTful 获取参数时默认值选项

    # 19.4.16  增加 SQLAlchemy翻页查询

    # 19.5.23  增加 SQLAlchemy增删改

    # 19.5.23  增加 SQLAlchemy取值限制

    # 19.5.30  增加 返回多个表

    # 19.5.30  增加 SQLAlchemy返回时间类型

    正文

    Flask-RESTful 获取url传参

    这里的url参数分为

    api/1  # url中捕捉参数

    api?aa=bb&cc=dd  # 正经的get传参(一key一v)

    第一种在路径中加入变量在我之前的博客中有写

    因其直接写在url中因此要在路由匹配部分捕捉

    commodity_api.add_resource(CommodityClassify, '/commodityclassify/<int:classify_id>', endpoint='commodityclassify')

    如上的路由会匹配所有 /commodiyclassify/数字 的url并将该数字传给 CommodityClassify 类,注意的是该类需要接受参数

    class CommodityClassify(Resource):
        # 商品分类相关
    
        def get(self, classify_id=None):
            pass

    第二种是在 url后传参,我们只需要在在接收时指定取值范围即可

    跟上一篇中的获取 body/form 的数据差不多

    parser = reqparse.RequestParser()  # 生成parser
    parser.add_argument('name', type=str, help='name error', required=True, location='args')  # 获取form中的name字段,不传报错
    parser.add_argument('pwd', type=str, help='pwd error', required=True, location='args')  # pwd
    args = parser.parse_args(strict=True)  # 获取值,如传多余字段报错

    RESTFul获取值时默认值

    比如我们在需要带翻页的接口时,我们通常给 page page_size 设立默认值(比如page不传默认1)

    那么在RESTFul中怎么设置呢?

    看 DEMO

            parser = reqparse.RequestParser()  # 生成parser
            parser.add_argument('commodityclassify_id', type=int, help='commodityclassify_id error', required=True, location='args')  # 获取get传参的commodityclassify_id
            parser.add_argument('page', type=int, default=1, help='page error', location='args')  # 页数(默认1)
            args = parser.parse_args(strict=True)  # 获取值,如传多余字段报错

    值得注意的是,如果你开启了 required(严格模式) 就不会走到默认值这一步,因为检测到你没有传送 指定值 就直接返回报错

    SQLAlchemy翻页查询

    当我们遇到量大的数据时,通常需要分页来保障json的大小

    SQLAlchemy分页与sql类似

    DEMO如下

    parser = reqparse.RequestParser()  # 生成parser
            parser.add_argument('commodityclassify_id', type=int, required=True, location='args')  # 获取get传参的commodityclassify_id
            parser.add_argument('page', type=int, default=1, location='args')  # 页数(默认1)
            parser.add_argument('page_size', type=int, default=20, location='form')  # 每页大小(默认20)
            args = parser.parse_args(strict=True)  # 获取值,如传多余字段报错
            session = mysql_DBSession()  # 生成session
            commoditys_obj = session.query(Commodity).filter(Commodity.fk_commdoity_on_commodity_classify_id==args['commodityclassify_id'] , Commodity.state==1).order_by(Commodity.update_time.desc()).limit(args['page_size']).offset((args['page']-1)*args['page_size']).all()  # 查询某个分类下所有商品按最后更新时间从近到远

    先接 limit(每页大小) 再接 offset(页数,注意数据库从0开始所以page要-1) 最后不要忘了接 all()

     SQLAlchemy增删改

    先引入model

    创建session

    obj = modelname(字段=值,.....)

    session.add(obj)

    session.commit()

    from config.config import mysql_DBSession
    from app.user.model import User
    session = mysql_DBSession()
    user_obj = User(
      phone = args["phone"],
      wx_openid = args["wx_openid"],
      wx_img = args["wx_img"],
      wx_name = args["wx_name"]
      )
    session.add(user_obj)
    session.commit()

    查找到对应obj

    直接给某个字段赋值

    commit()

    session = mysql_DBSession()
    obj=session.query(UserOrderForm).filter(UserOrderForm.fk_user_orderform_on_user_id==args["user_id"],UserOrderForm.id==id).first()
    obj.status == '1'
    obj.use_time == datetime.datetime.now()
    session.commit()

    查找到这个obj

    session.delete(obj)

    session.commit()

     SQLAlchemy取值限制

    如果有这样的需求

    限定接口接收参数 file 的值为 某个范围中的一个

    使用 

    choices=("faf", "faf") # choices代表必须在这个范围内

    parser = reqparse.RequestParser()
            parser.add_argument('file', type=str, required=True, location='form', choices=("faf", "faf"))
            args = parser.parse_args(strict=True)

     一个对象包含多表

    如果我们在一个对象返回多个表时

    session.query(表1, 表2)

    返回为

    [

    [表1],

    [表2]

    ]

    SQLAlchemy 返回Datetime

    近日在使用 SQLalchemy 的序列化组件的时候遇到了一个问题

    就是数据库的Datetime类型在序列化的时候使用 fields.DateTime() 会转换成字符串

    model

    found_time = Column(DateTime, nullable=False)

    field

    "found_time": fields.DateTime(),

    返回值为

    "found_time": "Tue, 28 May 2019 09:38:51 -0000",

    我们来尝试查看fields的源码

    class DateTime(Raw):
        """
        Return a formatted datetime string in UTC. Supported formats are RFC 822
        and ISO 8601.
    
        See :func:`email.utils.formatdate` for more info on the RFC 822 format.
    
        See :meth:`datetime.datetime.isoformat` for more info on the ISO 8601
        format.
    
        :param dt_format: ``'rfc822'`` or ``'iso8601'``
        :type dt_format: str
        """
        def __init__(self, dt_format='rfc822', **kwargs):
            super(DateTime, self).__init__(**kwargs)
            self.dt_format = dt_format
    
        def format(self, value):
            try:
                if self.dt_format == 'rfc822':
                    return _rfc822(value)
                elif self.dt_format == 'iso8601':
                    return _iso8601(value)
                else:
                    raise MarshallingException(
                        'Unsupported date format %s' % self.dt_format
                    )
            except AttributeError as ae:
                raise MarshallingException(ae)

    也就是说,默认的输出实际上是 rfc822 格式的字符串

    这是一种时间格式,我们也看到,如果我们使用DateTime方法格式化,只能使用 rfc822 或者 iso8601 

    在WEB开发中,想要前端页面显示 rfc822 格式的时间,无疑是麻烦的,所以我们可以使用 iso8601

    fileds

    "found_time": fields.DateTime(dt_format="iso8601"),

    结果为

    "found_time": "2019-05-28T09:38:51",

    这种就令前端渲染方便得多

    当然我认为使用时间戳更好,但是我目前还没有找到怎样做

    以上方法可以先用着

  • 相关阅读:
    写作 —— 细节与画面感
    写作 —— 细节与画面感
    诸子经典 —— 《管子》
    诸子经典 —— 《管子》
    金庸小说的模式
    金庸小说的模式
    SQLite中如何用api操作BLOB类型的字段
    Android WebView挂马漏洞--各大厂商纷纷落马
    [置顶] android开发之来电自动拒接并自动回复短信_上课模式app
    步步为营Hibernate全攻略(四)剪不断理还乱之:复合主键 && 组合映射
  • 原文地址:https://www.cnblogs.com/chnmig/p/10712230.html
Copyright © 2011-2022 走看看