Flask+MongoAlchemy出现BadValueException:日期字段类型不匹配
解决Flask+MongoAlchemy的BadValueException:日期字符串转datetime对象
我之前也踩过这个坑!HTML的datetime-local控件提交的是ISO格式的字符串,而MongoAlchemy的DateTimeField只认datetime.datetime实例——直接编码UTF8根本解决不了类型问题,必须做显式的类型转换。
问题根源
BadValueException: 类型为"date_deadline"的字段值无效。原因:"Value is not an instance of <type 'datetime.datetime'> (got: str)"
这个错误说得很明白:你给DateTimeField传了字符串,但它需要的是datetime对象。request.form.get('date')拿到的本来就是字符串,encode('utf8')要么是把字符串转成字节串(Python 2环境下),要么完全没用(Python 3里字符串默认就是UTF8编码),本质上还是没把类型转成datetime。
解决方案:把日期字符串转成datetime对象
有两种常用的转换方式,选适合你的就行:
方式1:用Python标准库的datetime.strptime
先导入datetime模块,然后按照datetime-local返回的固定格式(YYYY-MM-DDTHH:MM)解析字符串:
修改后的Python代码:
from datetime import datetime from flask import Flask, request, render_template from flask_mongoalchemy import MongoAlchemy app = Flask(__name__) db = MongoAlchemy(app) class Model(db.Document): name = db.StringField() date_added = db.DateTimeField() # 注意字段名要和后续实例创建时对应! @app.route('/form', methods=['GET', 'POST']) def form(): if request.form.get('submit'): get_name = request.form.get('name') get_date_str = request.form.get('date') # 处理日期转换,先判断是否为空 if get_date_str: try: # 按照datetime-local的格式转成datetime对象 get_date = datetime.strptime(get_date_str, '%Y-%m-%dT%H:%M') except ValueError: # 处理格式错误的情况,返回提示 return "日期格式不正确,请重新选择" else: get_date = datetime.now() # 或者设为None,根据业务需求调整 # 注意字段名要和Model类里定义的一致(之前的代码里写的date是错的) new_model = Model(name=get_name, date_added=get_date) new_model.save() return render_template('form.html')
方式2:用python-dateutil(更灵活,兼容多格式)
如果担心前端提交的日期格式有变化,或者想兼容更多格式,可以用python-dateutil库:
- 先安装依赖:
pip install python-dateutil - 导入并替换转换逻辑:
from dateutil.parser import parse # 替换转换部分的代码 get_date = parse(get_date_str)
这个方法不需要指定格式,能自动识别大部分常见的日期字符串格式,非常省心。
额外注意点
- 你的
Model类里定义的日期字段是date_added,但原代码创建实例时写的是date = get_date,这会导致字段不匹配,一定要修正! - 如果前端可能提交空日期,记得加判断,避免转换时抛出异常。
- MongoAlchemy会自动把datetime对象转换成MongoDB支持的日期类型存储,不需要手动处理编码。
内容的提问来源于stack exchange,提问作者IntFooBar
相关产品推荐
相关产品推荐

