将日期作为URL参数传递到Flask路由

9
我希望过滤一些与url和日期参数(例如url.com?start=2018-12-12)相关的数据库结果。读取参数的常规方式是使用request.args.get,访问底层ImmutableMultiDict的值,它给出了可选的defaulttype参数。
我第一次尝试的代码如下:
@app.route()
def event():
   ektempo = request.args.get('start', default = datetime.date.today(), type = datetime.date)
   ...

对于默认参数来说是有效的,但对于传递的日期字符串则无效,因为datetime.date需要三个整数作为参数。通常我会通过datetime.datetime.strptime和一个格式字符串来获取我的日期对象。有没有一种方法可以将日期字符串作为url参数传递到flask中,并将其转换为datetime.date

我喜欢request.args.get的工作方式,但似乎我不能轻松地从给定的url参数中获取datetime.date对象。是否有其他方法可以通过flask内置方法实现,该方法验证参数并在没有参数或ValueError时返回默认值?


获取日期字符串,然后将其转换为 datetime.date,作为单独的步骤。 - John Gordon
就我看来,你似乎试图将太多的逻辑压缩到一行代码中。我建议先获取字符串(无论是默认值还是从请求中获取),然后再考虑将其转换为日期对象。 - DeepSpace
为什么不直接像数字那样传递日期,比如20181212120222,表示2018年12月12日12点02分22秒,然后在你的端点内解析成日期? - dmitryro
但是我指的是对于其他类型,它完美地运作... 对我来说,如果我有一个类型和一个“转换”参数,那就完美了。我的意思是你不能期望一个适合URL参数的东西总是映射到对象的构造函数... 不知道,也许request.args.get只是为原始类型而设计的,但对我来说,这似乎是一件太基本的事情了,你可以有一些可能性,来获取日期或地理坐标验证器用于URL参数...不知道...对我来说,手动验证这些基本类型对于网站来说似乎太多了... - Paul Würtz
2
我不确定你在这里所做的类型和转换参数之间的区别。类型参数已经是可调用的,你可以在那里传递自己的函数,它接受一个字符串并返回任何你想要的内容。 - Daniel Roseman
你说得完全正确!我以为它与Python内置的“type”关键字有关,只能在那里传递一个类,但实际上你可以传递任何函数!太棒了,非常感谢!!! - Paul Würtz
2个回答

16

正如 Daniel Roseman 指出的那样,您可以将任何函数传递给 type,因此我只定义了一个小助手函数来转换日期字符串,它就在这里:

def toDate(dateString): 
    return datetime.datetime.strptime(dateString, "%Y-%m-%d").date()

@app.route()
def event():
    ektempo = request.args.get('start', default = datetime.date.today(), type = toDate)
    ...

太酷了,非常感谢Daniel,这正是我所寻找的!:)


6
已被接受的解决方案适用于该用例(并获得了我的赞成:);然而,如果参数不符合预期格式,则会将其静默地设置为默认值(今天),对调用者没有任何反馈-因为这是flask/werkzeug的预期行为。
以下是如何使用它来验证并返回错误,如果客户端传递了无效值-沿用OP的解决方案:
from flask import jsonify

def to_date(date_string): 
    try:
        return datetime.datetime.strptime(date_string, "%Y-%m-%d").date()
    except ValueError:
        raise ValueError('{} is not valid date in the format YYYY-MM-DD'.format(date_string))

@app.route()
def event():
    try:
        ektempo = to_date(request.args.get('start', default = datetime.date.today().isoformat()))
    except ValueError as ex:
        return jsonify({'error': str(ex)}), 400   # jsonify, if this is a json api


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接