• 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",

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

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

    以上方法可以先用着

  • 相关阅读:
    jsp转向
    什么是 XDoclet?
    tomcat中的几点配置说明
    mysql5问题
    POJ 3734 Blocks
    POJ 2409 Let it Bead
    HDU 1171 Big Event in HDU
    POJ 3046 Ant Counting
    HDU 2082 找单词
    POJ 1286 Necklace of Beads
  • 原文地址:https://www.cnblogs.com/chnmig/p/10712230.html
Copyright © 2020-2023  润新知