首页 > 解决方案 > Flask API - 按字段单表创建嵌套的 json 响应组

问题描述

我有一个基本的 API 设置,可以从单个表中执行基本的 Post 和 Get。我想通过 force_element_type 分组来创建一个嵌套数组

模型.py

from db import db
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import text as sa_text

class ForceElementModel(db.Model):
    __tablename__ = 'force_element'
    __table_args__ = {'schema': 'force_element'}

    force_element_id = db.Column(UUID(as_uuid=True), primary_key=True, server_default=sa_text("uuid_generate_v4()"))
    name = db.Column(db.String(100), nullable=False)
    force_element_type = db.Column(db.String(20), nullable=False)

    def __init__(self, name, force_element_type):
        self.name = name
        self.force_element_type = force_element_type

    def json(self):
        return {'name': self.name, 'force_element_type': self.force_element_type}

    @classmethod
    def find_by_name(cls, name):
        return cls.query.filter_by(name=name).first()  # simple TOP 1 select

    def save_to_db(self):  # Upserting data
        db.session.add(self)
        db.session.commit()  # Balla

    def delete_from_db(self):
        db.session.delete(self)
        db.session.commit()

资源.py

from flask_restful import Resource, reqparse
#from flask_jwt import jwt_required
from models.force_element import ForceElementModel

class ForceElement(Resource):
    parser = reqparse.RequestParser()  # only allow price changes, no name changes allowed
    parser.add_argument('force_element_type', type=str, required=True, help='This field cannot be left blank')

    #@jwt_required()
    def post(self, name):
        if ForceElementModel.find_by_name(name):
            return {'message': "An Force Element with name '{}' already exists.".format(name)}, 400

        data = ForceElement.parser.parse_args()
        force_element = ForceElementModel(name, data['force_element_type'])

        try:
            force_element.save_to_db()
        except:
            return {"message": "An error occurred inserting the item."}, 500
        return force_element.json(), 201


class ForceElementList(Resource):
    #@jwt_required()
    def get(self):
        return {'force_elements': [force_element.json() for force_element in ForceElementModel.query.all()]}
    
class ForceElementType(Resource):
    #@jwt_required()
    def get(self):

使用 ForceElementList 的 GET 端点返回

    {
    "force_elements": [
        {
            "name": "San Antonio",
            "force_element_type": "ship"
        },
        {
            "name": "Nimitz",
            "force_element_type": "ship"
        },
        {
            "name": "Nimitz- Starboard",
            "force_element_type": "Crew"
        },
        {
            "name": "Nimitz- Port",
            "force_element_type": "Crew"
        }
    ]
}

我不知道如何按 force_element_type 分组并返回

[
"ship": [
    {
        "name": "San Antonio",
        "force_element_id": "xxx1"
    },
    {
        "name": "Nimitz",
        "force_element_id": "xxx2"
    }],
"crew": [
    {
        "name": "Nimitz- Starboard",
        "force_element_id": "yyy1"
    },
    {
        "name": "Nimitz- Port",
        "force_element_id": "yyy2"
    }
]

]

如何创建这个单独的和点?

标签: python-3.xrestflaskflask-sqlalchemy

解决方案


好的,我到了那里,这就是我的做法。有没有更好的办法?

第一课使用在线解析器检查 json 格式,这是我真正的目标,然后开始时的方括号让我摸不着头脑

{
"ship": [
    {
        "name": "San Antonio",
        "force_element_id": "xxx1"
    },
    {
        "name": "Nimitz",
        "force_element_id": "xxx2"
    }],
"crew": [
    {
        "name": "Nimitz- Starboard",
        "force_element_id": "yyy1"
    },
    {
        "name": "Nimitz- Port",
        "force_element_id": "yyy2"
    }]
}

此代码为输出创建正确的格式

class ForceElementType(Resource):
    #@jwt_required()
    def get(self):
        types = {}
        force_elements = ForceElementModel.query.order_by(ForceElementModel.force_element_type.desc()).all()
        for force_element in force_elements:
            nested = {'name':  force_element.name, 'force_element_id': str(force_element.force_element_id)}
            print(nested)
            if not force_element.force_element_type in types:
                types[force_element.force_element_type] = []
            types[force_element.force_element_type].append(nested)

        response = types

推荐阅读