#python #python-3.x #flask
Вопрос:
Я создаю веб-приложение с помощью Flask. Это панель мониторинга моего маркетингового программного обеспечения. В моем маркетинговом программном обеспечении пользователи могут создавать некоторые кампании.
В кампании есть несколько задач. Когда пользователь хочет отредактировать задачу, я получаю эту страницу «Внутренняя ошибка сервера».
Когда я проверяю журнал, я вижу эту ошибку:
TypeError: Object of type Row is not JSON serializable
Поэтому я добавил несколько «print()» везде, чтобы определить строку, которая вызывает эту проблему.
Я думаю, что нашел его, но там нет абсолютно ничего от json!
Это часть кода:
print(f"2409 ==================================================================================")
print(f"""
platform_details.name : {platform_details.name} {type(platform_details.name)}
categories_platforms : {categories_platforms} {type(categories_platforms)}
platform_details : {platform_details} {type(platform_details)}
category : {category} {type(category)}
task : {task} {type(task)}
type_task : {type_task} {type(type_task)}
taskuser : {taskuser} {type(taskuser)}
campaign : {campaign} {type(campaign)}
list_place_holders : {list_place_holders} {type(list_place_holders)}
form : {form} {type(form)}
AB_testing_result : {AB_testing_result} {type(AB_testing_result)}
""")
return render_template('task.html', title=platform_details.name,
categories_platforms=categories_platforms,
platform_details=platform_details, category=category, task=task,
type_task=type_task, taskuser=taskuser, campaign=campaign,
list_place_holders=list_place_holders, form=form,
AB_testing_result=AB_testing_result)
Поскольку я подозреваю, что проблема связана с одним из параметров, переданных в «render_template», я решил распечатать значение переменной и тип.
Это журнал:
2409 ==================================================================================
platform_details.name : Instagram <class 'str'>
categories_platforms : [[(1, 'Cold Messaging', 'cold_messaging', '<i class="mdi mdi-message-text-outline menu-icon"></i>', ''), [(15, 'Facebook', '<i class="mdi mdi-facebook-box"></i>', ''), (23, 'Google_Map', '<i class="mdi mdi-google-maps"></i>', ''), (22, 'Instagram', '<i class="mdi mdi-instagram"></i>', ''), (4, 'Linkedin', '<i class="mdi mdi-linkedin"></i>', ''), (45, 'Reddit', '<i class="mdi mdi-reddit"></i>', ''), (24, 'sms', '<i class="mdi mdi-comment-text"></i>', ''), (11, 'Telegram', '<i class="mdi mdi-telegram"></i>', ''), (3, 'Twitter', '<i class="mdi mdi-twitter"></i>', ''), (12, 'Whatsapp', '<i class="mdi mdi-whatsapp"></i>', '')]], [(2, 'Influencers', 'influencers', '<i class="mdi mdi-human-greeting menu-icon"></i>', ''), [(25, 'Facebook', '<i class="mdi mdi-facebook-box"></i>', ''), (26, 'Instagram', '<i class="mdi mdi-instagram"></i>', ''), (28, 'Linkedin', '<i class="mdi mdi-linkedin"></i>', ''), (9, 'Reddit', '<i class="mdi mdi-reddit"></i>', ''), (29, 'Telegram', '<i class="mdi mdi-telegram"></i>', ''), (42, 'TikTok', '', 'tiktok_blue.png'), (27, 'Twitter', '<i class="mdi mdi-twitter"></i>', ''), (10, 'Youtube', '<i class="mdi mdi-youtube"></i>', '')]], [(3, 'Scraping', 'scraping', '<i class="mdi mdi-database menu-icon"></i>', ''), [(7, 'Craigslist', '', 'craigslist_blue.png'), (36, 'Facebook', '<i class="mdi mdi-facebook-box"></i>', ''), (35, 'Google_Map', '<i class="mdi mdi-google-maps"></i>', ''), (33, 'Instagram', '<i class="mdi mdi-instagram"></i>', ''), (5, 'Leboncoin', '', 'leboncoin_blue.png'), (31, 'Linkedin', '<i class="mdi mdi-linkedin"></i>', ''), (8, 'Pages Jaunes', '', 'pagesjaunes_blue.png'), (6, 'YellowPages', '', 'yellow_pages_blue.png')]], [(4, 'Authority', 'authority', '<i class="mdi mdi-shape-plus menu-icon"></i>', ''), [(34, 'Facebook', '<i class="mdi mdi-facebook-box"></i>', ''), (37, 'Instagram', '<i class="mdi mdi-instagram"></i>', ''), (43, 'Linkedin', '<i class="mdi mdi-linkedin"></i>', ''), (44, 'TikTok', '', 'tiktok_blue.png'), (38, 'Twitter', '<i class="mdi mdi-twitter"></i>', '')]], [(5, 'Freelancer', 'freelancer', '<i class="mdi mdi-worker menu-icon"></i>', ''), [(39, 'Freelancer', '', 'freelancer_blue.png'), (40, 'Upwork', '', 'upwork_blue.png')]]] <class 'list'>
platform_details : Platform('37','Instagram','instagram_automation.jpg','<h3 class="card-title" style="font-size:1.1em;">
<i class="mdi mdi-download"></i>
Your data
</h3>
<p>
After the job is done, you will find the report of activity in the campaign report page.
</p>
<p>
It can take a very long time to automate safetly.
<p>
The more tasks PhoneBot has to do, the more time it will take to accomplish this Authority task. If you are in hurry, please create a new campaign dedicated only to Authority.
</p>','4', '<i class="mdi mdi-instagram"></i>','','','','1') <class 'dashboard.models.Platform'>
category : Category('4','Authority','authority','<i class="mdi mdi-shape-plus menu-icon"></i>','','','') <class 'dashboard.models.Category'>
task : Task('34','Auto-Follow','<p>PhoneBot will follow the Instagram Followers of specific accounts (i.e.: some influencers or your competitors). You need to provide a list of urls of these specific accounts. ','<h3 class="card-title" style="font-size:1.1em;">
<i class="mdi mdi-information-outline"></i>
NOTIFICATION
</h3>
<p>You will be able to see the progress of this task on the report home page of your campaign .</p>
</p>', '37','7','75','1','1','1') <class 'dashboard.models.Task'>
type_task : TypeTask('7','Follow') <class 'dashboard.models.TypeTask'>
taskuser : TaskUser('1182','None','34','44','None','None', 'None',None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None', 'None') <class 'dashboard.models.TaskUser'>
campaign : Campaign('44','1','40','popop','2021-06-29 11:10:57','178') <class 'dashboard.models.Campaign'>
list_place_holders : {username}, {random_abc} <class 'str'>
form : <dashboard.forms.NewTaskUserForm object at 0x7f0d8ec25490> <class 'dashboard.forms.NewTaskUserForm'>
AB_testing_result : (1182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) <class 'tuple'>
[2021-09-24 08:07:21,505] ERROR in app: Exception on /task_user/1182/edit [GET]
Traceback (most recent call last):
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/app.py", line 1516, in full_dispatch_request
return self.finalize_request(rv)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/app.py", line 1537, in finalize_request
response = self.process_response(response)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/app.py", line 1886, in process_response
self.session_interface.save_session(self, ctx.session, response)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/sessions.py", line 394, in save_session
val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/itsdangerous/serializer.py", line 207, in dumps
payload = want_bytes(self.dump_payload(obj))
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/itsdangerous/url_safe.py", line 53, in dump_payload
json = super().dump_payload(obj)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/itsdangerous/serializer.py", line 169, in dump_payload
return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/json/tag.py", line 308, in dumps
return dumps(self.tag(value), separators=(",", ":"))
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/json/__init__.py", line 129, in dumps
rv = _json.dumps(obj, **kwargs)
File "/www/server/panel/pyenv/lib/python3.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/www/server/panel/pyenv/lib/python3.7/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/www/server/panel/pyenv/lib/python3.7/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/json/__init__.py", line 56, in default
return super().default(o)
File "/www/server/panel/pyenv/lib/python3.7/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Row is not JSON serializable
[2021-09-24 08:07:21,507] ERROR in app: Request finalizing failed with an error while handling an error
Traceback (most recent call last):
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/app.py", line 2070, in wsgi_app
response = self.full_dispatch_request()
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/app.py", line 1516, in full_dispatch_request
return self.finalize_request(rv)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/app.py", line 1537, in finalize_request
response = self.process_response(response)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/app.py", line 1886, in process_response
self.session_interface.save_session(self, ctx.session, response)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/sessions.py", line 394, in save_session
val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/itsdangerous/serializer.py", line 207, in dumps
payload = want_bytes(self.dump_payload(obj))
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/itsdangerous/url_safe.py", line 53, in dump_payload
json = super().dump_payload(obj)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/itsdangerous/serializer.py", line 169, in dump_payload
return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/json/tag.py", line 308, in dumps
return dumps(self.tag(value), separators=(",", ":"))
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/json/__init__.py", line 129, in dumps
rv = _json.dumps(obj, **kwargs)
File "/www/server/panel/pyenv/lib/python3.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/www/server/panel/pyenv/lib/python3.7/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/www/server/panel/pyenv/lib/python3.7/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/json/__init__.py", line 56, in default
return super().default(o)
File "/www/server/panel/pyenv/lib/python3.7/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Row is not JSON serializable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/app.py", line 1537, in finalize_request
response = self.process_response(response)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/app.py", line 1886, in process_response
self.session_interface.save_session(self, ctx.session, response)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/sessions.py", line 394, in save_session
val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/itsdangerous/serializer.py", line 207, in dumps
payload = want_bytes(self.dump_payload(obj))
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/itsdangerous/url_safe.py", line 53, in dump_payload
json = super().dump_payload(obj)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/itsdangerous/serializer.py", line 169, in dump_payload
return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/json/tag.py", line 308, in dumps
return dumps(self.tag(value), separators=(",", ":"))
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/json/__init__.py", line 129, in dumps
rv = _json.dumps(obj, **kwargs)
File "/www/server/panel/pyenv/lib/python3.7/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/www/server/panel/pyenv/lib/python3.7/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/www/server/panel/pyenv/lib/python3.7/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/home/www/dashboard.phonebot.co/dashboard.phone_venv/lib/python3.7/site-packages/flask/json/__init__.py", line 56, in default
return super().default(o)
File "/www/server/panel/pyenv/lib/python3.7/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Row is not JSON serializable
Чтобы убедиться, что проблема не связана с шаблоном «task.html», я опорожнил его и воспроизвел ошибку. Я получаю те же журналы ошибок.
Я не понимаю, почему возникает эта проблема с json, когда я не использую json. Является ли это «render_template», который jsonify данные перед передачей в шаблон? Кто-нибудь уже сталкивался с этой проблемой?
Здесь кто-то пытался это исправить, но безуспешно (( https://youtu.be/4su2FDJRrH8
Ответ №1:
Вызов сериализации поступает из finalize_request->save_session. Таким образом, это постобработка фреймворком. Некоторые фреймворки сохраняют содержимое сеанса на диск, чтобы освободить память. (Может быть настройка для управления этим). Вероятно, вы сохранили объект строки в сеансе, поэтому он пытается сериализовать его, и, следовательно, произошла ошибка. Решение состоит в том, чтобы не сохранять строку в сеансе или не делать строку сериализуемой. Видишь https://pynative.com/make-python-class-json-serializable/
Комментарии:
1. Огромное спасибо. Это интересно. Я буду работать над этим и, возможно, вернусь к вам.
2. Я не понимаю, потому что я не сохраняю в сеансе ни один из параметров render_template. я тоже не использую JSON. Поэтому я не знаю, как обращаться с вашим учебником в моем конкретном случае.
3. Привет, ошибка очевидна, что она не может сериализовать данные. Означает, что вы не можете создать json.
4. @GauthierButtez, сохранение сеанса-это не часть вашей бизнес-логики, а то, что фреймворк делает сам по себе для сохранения состояния сеанса. Вы сохранили объект строки в сеансе или нет ? Там может быть флаг, чтобы изменить это поведение. Или используйте учебник, чтобы сделать класс строк сериализуемым.
5. спасибо @manojmo. Я использую объектную колбу «сеанс» для сохранения некоторых данных во время сеанса пользователя. Но ни одно из значений словаря сеанса не передается в «render_template». Это выводит меня из себя.??