无法获取我的响应JSON上的枚举值

kmb7vmvb  于 2023-10-21  发布在  其他
关注(0)|答案(1)|浏览(133)

我现在正在为我的学习构建flask项目,现在我有这样的员工简单模式(没有添加所有列名):

class GenderChoices(enum.Enum):
    M = 'M'
    F = 'F'

    def __str__(self):
        return self.name

    @staticmethod
    def from_string(s):
        try:
            return GenderChoices[s]
        except KeyError:
            raise ValueError()

class Employees(db.Model):
    ___tablename___ = "employees"

    emp_no = db.Column(db.Integer, primary_key=True)
    gender = db.Column(db.Enum(GenderChoices, values_callable=lambda x: [str(member.value)
                                                                         for member in GenderChoices]))

关于资源方面的基本参数,我是这样传递的:

parser.add_argument('gender',
                    type=GenderChoices.from_string,
                    help='This field cannot be blank',
                    required=True,
                    choices=list(GenderChoices))

我的回答是这样的:

return {
            'message': 'New Employee Has been created',
            'Employee_Details': {
                'employee_id': new_id,
                'gender': data['gender']
            }
        }, 201

虽然运行我的脚本添加员工运行良好,它存储在我的数据库中的数据,以及,但在显示我的结果 Postman ,我得到以下错误:

TypeError: Object of type GenderChoices is not JSON serializable

似乎有什么问题。

ghhkc1vu

ghhkc1vu1#

Flask-RESTful

如果你使用的是Flask-RESTful,你可以通过使用@marshal_with装饰器并指定一个field.String来强制转换为字符串。

from flask import (
    Flask, 
    render_template, 
    request
)
from flask_restful import (
    Api, 
    Resource, 
    fields, 
    marshal_with, 
    reqparse
)
from flask_sqlalchemy import SQLAlchemy
import enum 

class GenderChoices(enum.Enum):
    M = 'M'
    F = 'F'

    def __str__(self):
        return self.name

    @staticmethod
    def from_string(s):
        try:
            return GenderChoices[s]
        except KeyError:
            raise ValueError()

app = Flask(__name__)
app.config.from_mapping(
    SECRET_KEY='your secret here', 
    SQLALCHEMY_DATABASE_URI='sqlite:///demo.db', 
)
db = SQLAlchemy(app)
api = Api(app)

parser = reqparse.RequestParser()
parser.add_argument('gender',
    type=GenderChoices.from_string,
    help='This field cannot be blank',
    required=True,
    choices=list(GenderChoices)
)

class Employee(db.Model):
    __tablename__ = "employees"
    id = db.Column(db.Integer, primary_key=True)
    gender = db.Column(db.Enum(GenderChoices, values_callable=lambda x: [str(member.value) for member in GenderChoices]))

with app.app_context():
    db.drop_all()
    db.create_all()

class EmployeeList(Resource):
    @marshal_with({
        'message': fields.String,
        'Employee_Details': fields.Nested({
            'employee_id': fields.Integer, 
            'gender': fields.String 
        })
    })
    def post(self):
        args = parser.parse_args()
        employee = Employee(**args)
        db.session.add(employee)
        db.session.commit()
        return {
            'message': 'New Employee Has been created',
            'Employee_Details': {
                'employee_id': employee.id,
                'gender': employee.gender
            }
        }, 201

api.add_resource(EmployeeList, '/employees')

flask

当使用纯 flask 时,您可以使用以下变体。
一方面,您可以使用StrEnum,其值可以在没有任何操作的情况下转换为JSON。

class GenderChoices(enum.StrEnum):
    M = 'M'
    F = 'F'

如果您想使用替代方法,可以创建一个自定义JSONProvider并在应用程序中使用它。下面的示例扩展DefaultJSONProvider

from flask.json.provider import DefaultJSONProvider

class CustomJSONProvider(DefaultJSONProvider):
    @staticmethod
    def default(o):
        if isinstance(o, enum.Enum):
            return o.name
        return DefaultJSONProvider.default(o)

app = Flask(__name__)
app.json_provider_class = CustomJSONProvider
app.json = CustomJSONProvider(app)

相关问题