TypeError:使用flask_jwt_extended int RESTful API时类型函数的对象不是JSON可序列化的

Posted

技术标签:

【中文标题】TypeError:使用flask_jwt_extended int RESTful API时类型函数的对象不是JSON可序列化的【英文标题】:TypeError: Object of type function is not JSON serializable when using flask_jwt_extended int RESTful API 【发布时间】:2021-05-17 20:58:21 【问题描述】:

我正在使用烧瓶构建 REST API。我正在使用邮递员测试在我的数据库中创建新项目的路线,但前提是用户已登录。注册和登录的路线运行良好,最后一个使用 flask_jwt_extended 模块返回令牌。当我向我的“/api/notes”发送一个发布请求(在数据库中创建一个新注释)时,我收到以下错误:

" (...) raise TypeError(f'Object of type o.class.name '

TypeError: 类型函数的对象不是 JSON 可序列化的"

对于我正在使用邮递员的授权选项卡的请求。 type:Bearer Token,字段中我的token(带引号和不带引号都试过)

我今天早上遇到了这个错误,在实施我的一对多关系之前,但我通过在 Barear 令牌字段中将我的 VERY_LONG_TOKEN 替换为“VERY_LONG_TOKEN”来使其正常工作。我认为因为令牌包含点,所以它被解释为一个函数。但是实现关系后,我去测试,又报这个错误。

我的 note.py 文件:

from flask import request, Response, jsonify
from app.models import User, Note
from flask_restful import Resource
from flask_jwt_extended import jwt_required, get_jwt_identity

class NotesApi(Resource):
    def get(self):
        notes = Note.objects().to_json()
        return Response(notes, mimetype="application/json", status=200)

    @jwt_required  
    def post(self):  # post method I'm making a request for
        print("fool")  # this doesn't get printed  ->  not reaching 
        user_id = get_jwt_identity()
        data = request.get_json(force=True)
        if data:
            user = User.objects(id=user_id) # logged in user
            note = Note(**data, user_author=user) # creates note with the author
            note.save()
            user.update(push__notes=note) # add this note to users notes
            user.save()
            id = str(note.id)
            return 'id': id, 200
        else:
            return 'error': 'missing data', 400

我的模型.py:

from app import db  # using mongodb
from datetime import datetime
from flask_bcrypt import generate_password_hash, check_password_hash

class Note(db.Document):
    title = db.StringField(max_length=120,required=True)
    content = db.StringField(required=True)
    status = db.BooleanField(required=True, default=False)
    date_modified = db.DateTimeField(default=datetime.utcnow)
    user_author = db.ReferenceField('User')
    
class User(db.Document):
    username = db.StringField(max_length=100, required=True, unique=True)
    email = db.StringField(max_length=120, required=True, unique=True)
    password = db.StringField(required=True)
    remember_me = db.BooleanField(default=False)
    notes = db.ListField(db.ReferenceField('Note', reverse_delete_rule=db.PULL)) # one-many relationship

    def hash_password(self):
        self.password = generate_password_hash(self.password).decode('utf8')

    def check_password(self, password):
        return check_password_hash(self.password, password)


User.register_delete_rule(Note, 'user_author', db.CASCADE)

初始化.py:

from flask import Flask
from config import Config  # my config class to set MONGOBD_HOST and SECRET_CLASS
from flask_mongoengine import MongoEngine
from flask_restful import Api
from flask_bcrypt import Bcrypt
from flask_jwt_extended import JWTManager

app = Flask(__name__)
app.config.from_object(Config)
db = MongoEngine(app)
api = Api(app)
bcrypt = Bcrypt(app)
jwt = JWTManager(app)

from app.resources.routes import initialize_routes
initialize_routes(api) 

资源/路由.py:

from .note import NotesApi, NoteApi
from .auth import SignupApi, LoginApi

def initialize_routes(api):
    api.add_resource(NotesApi, '/api/notes')
    api.add_resource(NoteApi, '/api/note/<id>')
    api.add_resource(SignupApi, '/api/auth/signup')
    api.add_resource(LoginApi, '/api/auth/login')

文件夹结构:

app
  |_ resources
      |_ auth.py  # signup working well, login also working, return a token (type = String)
      |_ note.py
      |_ routes.py
  |_ __init__.py
  |_ models.py
config.py
appname.py  #just import app and do a app.run()

我的帖子请求正文:


   "title": "test0",
   "content": "test0"  

有没有人遇到过或知道如何解决它?

编辑:添加更多代码信息

【问题讨论】:

你能提供一个minimal reproducible example吗?作为这里的新用户,也请带上tour并阅读How to Ask。 抱歉,我编辑了我的问题,添加了更多信息。谢谢。 @WilianeSouza 应用在 note.py 文件中的什么地方中断? 它没有在回溯中指向我的任何代码行,但我根据 Maylor 的回答解决了这个问题。谢谢。 【参考方案1】:

只需摆脱对我有用的 HTTP 状态代码。例子

替换:

return 'id': id, 200

与:

return 'id': id

或:

resp = jsonify('id': id)

resp.status_code = 200

return resp

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:

好像 flask-jwt-extended 在周末发布了一个新版本。作为 API 更改的一部分,@jwt_required 装饰器现在是 @jwt_required()

https://flask-jwt-extended.readthedocs.io/en/stable/v4_upgrade_guide/#api-changes

【讨论】:

不知道你为什么提到“jtw”而不是“jwt”

以上是关于TypeError:使用flask_jwt_extended int RESTful API时类型函数的对象不是JSON可序列化的的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:str()最多使用1个参数(给定2个,TypeError:需要一个整数)

TypeError:无法使用玩笑读取未定义的属性“原型”

TypeError:“图像”对象不能使用 PIL 进行下标

使用敲除和微风时“TypeError:对象不是函数”

TypeError:无法使用 React 读取未定义的属性

TypeError:无法使用 discord.js 读取属性“”错误