在Flask请求上自动将JSON转换为Object

Rap*_*edo 3 python java json spring-mvc flask

在Spring MVC + Jackson(Java)中,我可以拥有:

我的对象(Java)

public class Project {

   private long id;
   private String self;
   private String key;
   private String name;

   //Getters and Setters
}
Run Code Online (Sandbox Code Playgroud)

Spring MVC控制器

...
@RequestMapping(value="/doSomething", method=RequestMethod.POST)
public String doSomething(@RequestBody Project project) {
    System.out.println(project.getName());
    return "myPage";
}
...
Run Code Online (Sandbox Code Playgroud)

然后,我可以发送一个json:

{"id": "exampleId", "name": "exampleName","self": "url","key": "key"}
Run Code Online (Sandbox Code Playgroud)

并自动转换为我的对象.在Python上,我有我的对象类.Flask中有些东西我可以打电话:

烧瓶控制器

@app.route('/doSomething', methods=['POST'])
def do_something(project):
    print project.name
    return "myPage"
Run Code Online (Sandbox Code Playgroud)

我的对象(Python)

class Project():

    id=None        
    name=None
    url=None
    key=None
Run Code Online (Sandbox Code Playgroud)

基本上,我想在Flask上收到我的JSON并且已经转换为我的Object.我想避免这样做:

class Project(object):
  def __init__(self, id, url, name, key):
    self.id = id
    self.url = url
    self.name = name
    self.key = key
...
import json
my_json = json.loads(request.data)
user = Project(**j)
Run Code Online (Sandbox Code Playgroud)

这样,我将不得不覆盖所有对象的init.或这个:

project = json.loads('{"__type__": "Project", "name": "project", "key": "key"}')
print project['name']
print project['key']
Run Code Online (Sandbox Code Playgroud)

不好,因为它不是我的对象,它是一个字典.

这可能吗?或者我必须选择其中之一?

jun*_*ony 7

据我所知,如果你必须在Python中使用一个类,我认为你不能避免添加构造函数.

另一种选择是使用namedtuple.它们就像元组,但带有字段名称.无论哪种方式,您都可以使用装饰器来模拟您想要的内容

例如:

from collections import namedtuple
Project = namedtuple('Project', 'id url name key')
Run Code Online (Sandbox Code Playgroud)

现在,您可以在视图处理程序中执行以下操作:

# This decorator takes the class/namedtuple to convert any JSON
# data in incoming request to. 
def convert_input_to(class_):
    def wrap(f):
        def decorator(*args):
            obj = class_(**request.get_json())
            return f(obj)
        return decorator
    return wrap

@app.route('/doSomething', methods=['POST'])
@convert_input_to(Project)
def do_something(project):
    print project.name
    return "myPage"
Run Code Online (Sandbox Code Playgroud)

另见flask.Request.get_json并确保'Content-Type'设置为'application/json'