Flask - TypeError: Object of type cycle ไม่สามารถต่ออนุกรม JSON ได้
ฉันกำลังพยายามส่งคืนการตอบสนอง json จากเซิร์ฟเวอร์ไปยังไคลเอนต์หลังจากไคลเอนต์โพสต์ผ่าน AJAX
แบบนี้มันใช้งานได้:
@app.route("/test", methods=["GET", "POST"])
@login_required
def test():
if request.is_xhr:
try:
json_response = {
"result": "success"
}
except Exception as e:
err = _except(line=sys.exc_info()[-1].tb_lineno, error=e, function_name=what_func(), script_name=__file__)
json_response = {"result": "failure", "msg": err}
return jsonify(json_response)
else:
return redirect("/not-found")
return ''
หากฉันทำเช่นนี้มันไม่ได้ผล:
@app.route("/test", methods=["GET", "POST"])
@login_required
def test():
if request.is_xhr:
try:
_dict = {
"key1": "value1",
"key2": "value2"
}
if not "my_dict" in session:
session["my_dict"] = [_dict]
else:
session["my_dict"] = session["my_dict"] + [_dict]
session.modified = True
json_response = {
"result": "success"
}
except Exception as e:
err = _except(line=sys.exc_info()[-1].tb_lineno, error=e, function_name=what_func(), script_name=__file__)
json_response = {"result": "failure", "msg": err}
return jsonify(json_response)
else:
return redirect("/not-found")
return ''
ฉันได้รับข้อผิดพลาดต่อไปนี้และไคลเอนต์ไม่ได้รับการตอบสนอง json:
File "~/myprojectenv/lib/python3.8/site-packages/flask/json/__init__.py", line 100, in default
return _json.JSONEncoder.default(self, o)
File "/usr/lib/python3.8/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type cycle is not JSON serializable
[2020-09-26 19:01:14,091] ERROR in app: Request finalizing failed with an error while handling an error
ถ้าฉันเอาความยืดนั้นออก:
if not "my_dict" in session:
session["my_dict"] = [_dict]
else:
session["my_dict"] = session["my_dict"] + [_dict]
session.modified = True
มันทำงานอีกครั้ง ลูกค้าได้รับการตอบสนอง json
คำตอบ
ฉันพบปัญหาแล้ว
ตรวจสอบฟังก์ชันต่อไปนี้:
@app.route("/test", methods=["GET", "POST"])
def test():
if request.is_xhr:
try:
licycle = cycle(files)
nextelem = next(licycle)
_dict = {
"sid": session["_id"],
"licycle": licycle,
"nextelem": nextelem,
"licycle2": licycle2,
"nextelem2": nextelem2,
"mon_id": _id,
"sch_id": 0
}
if not "all_submons" in session:
session["all_submons"] = [_dict]
else:
session["all_submons"] = session["all_submons"] + [_dict]
session.modified = True
all_submons.setdefault("sub_mons", []).append(_dict)
json_response = {"result": "success"}
except Exception as e:
err = _except(line=sys.exc_info()[-1].tb_lineno, error=e, function_name=what_func(), script_name=__file__)
json_response = {"result": "failure", "err": err}
finally:
try:
print("exiting...")
except Exception as e:
pass
return jsonify(json_response)
else:
return redirect("/not-found")
return ""
เหตุผลก็คือตัวแปรประเภท licycle คือ <class 'itertools.cycle'> และ session "อาจไม่ยอมรับ" ตัวแปรประเภทนั้นเช่นพจนานุกรมยอมรับตามที่คุณเห็นในตัวแปร all_submons dict ของฉัน
ประเด็นก็คือ:
การดำเนินการไม่ล้มเหลวในข้อยกเว้น และ _dict จะถูกเก็บไว้ในเซสชันดังที่คุณเห็นต่อไป
print(f"Session before: {session}")
print(f"all_submons before: {all_submons}")
if not "all_submons" in session:
session["all_submons"] = [_dict]
else:
session["all_submons"] = session["all_submons"] + [_dict]
session.modified = True
all_submons.setdefault("sub_mons", []).append(_dict)
print(f"Session after: {session}")
print(f"all_submons after: {all_submons}\n")
คุณสามารถตรวจสอบผลลัพธ์:
Session before: <SecureCookieSession {'_fresh': True, '_id': 'e253a950...', 'all_submons': [], 'user_id': '1'}>
all_submons before: {}
Session after: <SecureCookieSession {'_fresh': True, '_id': 'e253a...', 'all_submons': [{'sid': 'e253a95...', 'licycle': <itertools.cycle object at 0x7fc989237280>, 'nextelem': ('1a4add0f275c7275.jpg',), 'licycle2': None, 'nextelem2': None, 'mon_id': 1, 'sch_id': 0}], 'user_id': '1'}>
all_submons after: {'sub_mons': [{'sid': 'e253a...', 'licycle': <itertools.cycle object at 0x7fd6f1a17b80>, 'nextelem': ('1a4add0f275c7275.jpg',), 'licycle2': None, 'nextelem2': None, 'mon_id': 1, 'sch_id': 0}]}
ฉันไม่แน่ใจเกี่ยวกับเซสชัน "อาจไม่ยอมรับ" ตัวแปรประเภทนั้น - <class 'itertools.cycle'>
แต่ฉันสร้างพจนานุกรมอื่นพร้อมตัวแปรอื่น ๆ โดยไม่มีประเภทของ itertools.cycle และใช้งานได้