使用 marshal_with 获取数据时获取空响应

问题描述 投票:0回答:1

所以,我正在 Flask 上进行自学,为了解决我的枚举问题,我正在使用

marshal_with
其中一位用户建议我..现在我在获取无效 ID 的数据时遇到问题..

我正在使用以下内容来获取回复:

def json(self):
    return {
        'data': {
            'employee_id': self.emp_no,
            'employee_name': self.first_name + " " + self.last_name,
            'gender': self.gender,
            'birth_date': self.birth_date,
            'hire_date': self.hire_date,
            'created_at': self.created_at.strftime("%Y-%m-%d %H:%M:%S"),
            'last_updated_at': self.last_updated_at.strftime("%Y-%m-%d %H:%M:%S")
        }
    }

@classmethod
def find_by_employee_id(cls, employee_id):
    return cls.query.filter_by(emp_no=employee_id).first()

在员工的资源部分,我实施了以下逻辑来获取终点结果:

class GetEmployee(Resource):
    @marshal_with({
        'data': fields.Nested({
            'employee_id': fields.Integer,
            'employee_name': fields.String,
            'gender': fields.String,
            'birth_date': fields.String,
            'hire_date': fields.String,
            'created_at': fields.Raw,
            'last_updated_at': fields.Raw
        })
    })
    def get(self, employee_id: int):
        employee = Employees.find_by_employee_id(employee_id)
        if not employee:
            return {'message': 'Employee Not Found'}, 404

        return employee.json(), 200

现在好的事情是,如果我在终点内输入有效的

employee_id
,我会得到很好的响应,但是如果我添加无效的 id(如 4,5),我会得到如下响应:

{
    "data": {
        "employee_id": 0,
        "employee_name": null,
        "gender": null,
        "birth_date": null,
        "hire_date": null,
        "created_at": null,
        "last_updated_at": null
    }
}

我期待的是我在

GetEmployee
类中添加的响应,即

{'message': 'Employee Not Found'}

问题出在哪里。

python-3.x flask flask-restful
1个回答
1
投票

如果没有找到条目,查询数据库时可能会抛出 404 错误。还可以定义在错误发生后自动调用

abort
时输出的错误消息。可以在 Flask-SQLAlchemy 文档的 “视图查询” 部分中找到说明。

以下示例以简化的方式向您展示了如何输出错误或资源。当然,如果有需要也可以手动调用

abort()

from flask import (
    Flask, 
    render_template, 
    request
)
from flask_restful import (
    Api, 
    Resource, 
    fields, 
    marshal_with, 
)
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import column_property
import enum 


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

    def __str__(self):
        return self.name

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

class Employee(db.Model):
    __tablename__ = "employees"
    id = db.Column(db.Integer, primary_key=True)
    
    firstname = db.Column(db.String(80), unique=False, nullable=False)
    lastname = db.Column(db.String(80), unique=False, nullable=False)
    name = column_property(firstname + ' ' + lastname)
    
    gender = db.Column(db.Enum(
        GenderChoices, 
        values_callable=lambda x: [str(member.value) for member in GenderChoices]
    ))
    
    # ...

    def to_dict(self):
        return {
            'employee_id': self.id,
            'employee_name': self.name,
            'gender': self.gender
            # ...
        }

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

    employee = Employee(
        firstname='User', 
        lastname='One', 
        gender=GenderChoices.M,
    )
    db.session.add(employee)
    db.session.commit()

class EmployeeRsrc(Resource):
    @marshal_with({
        'data': fields.Nested({
            'employee_id': fields.Integer, 
            'employee_name': fields.String,  
            'gender': fields.String 
            # ...
        })
    })
    def get(self, employee_id):
        employee = db.get_or_404(
            Employee, employee_id, 
            description='Employee Not Found'
        )
        return {
            'data': employee.to_dict()
        }

api.add_resource(EmployeeRsrc, '/employees/<employee_id>')

如果您想输出任何错误消息(包括状态代码),您可以使用

abort(code, *args, **kwargs)
。执行立即结束并引发异常,该异常由错误处理程序捕获,并发送响应。

from flask_restful import abort

class MyRsrc(Resource):
    def post(self):
        # ...
        abort(422, description='Email invalid')
© www.soinside.com 2019 - 2024. All rights reserved.