如何使用Blask_smorest/Marshmallow的参数列表

发布于 2025-01-19 00:44:31 字数 737 浏览 1 评论 0原文

我正在尝试将对象集合插入烧瓶API。我们使用棉花糖进行挑选。我的终点看起来像这样:

        @blp.arguments(SomeSchemas, location='json', as_kwargs=True)
        @blp.response(200, SomeSchemas)
        def post(self, some_schemas: SomeSchemas) -> dict:

架构是一个简单的架构:

class SomeSchemas(ma.Schema):
    schemas = ma.fields.List(ma.fields.Nested(SomeSchema))

class SomeSchema(ma.Schema):
    a = ma.fields.String()
    b = ma.fields.Integer()

当我发布到端点时,我确实会得到正确的数据列表,但它以dicts的形式出现,而不是正确地翻译成对象。

我还尝试使用一个对象列表(列表[someschema],someschema(More = true)等)明确尝试过,但我似乎无法弄清楚。

我认为这是一个非常常见的用例(提供参数列表),并且我缺少一个明显的解决方案,但是我似乎找不到有关如何正确执行此操作的任何参考。需要明确的是,我正在寻找使用列表(或某些其他集合类型,没关系)调用端点的正确方法,并且已经正确审理了列表,并使用正确的对象类型进行了序列化。

I am trying to insert a collection of objects in a flask api. We use marshmallow for deserializing. My endpoint looks like this:

        @blp.arguments(SomeSchemas, location='json', as_kwargs=True)
        @blp.response(200, SomeSchemas)
        def post(self, some_schemas: SomeSchemas) -> dict:

The schema is a simple schema like this:

class SomeSchemas(ma.Schema):
    schemas = ma.fields.List(ma.fields.Nested(SomeSchema))

class SomeSchema(ma.Schema):
    a = ma.fields.String()
    b = ma.fields.Integer()

When i post to the endpoint, I do get a list of the correct data, but it comes in the form of dicts, instead of being correctly translated into the object.

I have also tried explicitly using a list of objects (List[SomeSchema], SomeSchema(many=True), etc.) but I can not seem to figure it out.

I assume this is a very common use case (providing a list of arguments) and that I am missing an obvious solution, but I can't seem to find any reference as to how to do this correctly. To be clear, I am looking for the correct way to call the endpoint with a list (or some other collection type, it does not matter) and have said list be correctly deserialized and with the correct object type.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

羁拥 2025-01-26 00:44:31

免责声明:flask-smoreest 维护者发言。

我认为该问题与输入是列表这一事实无关。

IIUC,你的问题是你得到的是字典,而不是对象,注入到视图函数中。这是默认的棉花糖行为。可以在 Marshmallow 中通过使用 post_load 钩子来实际实例化对象来覆盖它。

我一般不这样做。在实践中,我发现在视图函数中实例化对象更好。例如,在 PUT 资源中,我更喜欢实例化数据库中的现有项目,然后用新数据更新它。在这种情况下,最好将新数据作为字典而不是对象。

可能没有一个单一的事实,在这里,这可能是一个观点问题,但是虽然在装饰器中实例化对象并传递给视图的想法很吸引人,但这可能是一种滥用的捷径。


我意识到这个答案属于“不知道,但你无论如何都不应该这样做”类型。只是说也许你不应该为实现这一目标而奋斗。

这就是说,如果它适用于非列表/非嵌套输入,我会感到惊讶,并且我想知道为什么它在这种情况下不起作用。

Disclaimer: flask-smorest maintainer speaking.

I don't think the issue is related to the fact that the input is a list.

IIUC, your problem is that you're gettings dicts, rather than objects, injected in the view function. This is the default marshmallow behaviour. It can be overridden in marshmallow by using a post_load hook to actually instantiate the object.

I generally don't do that. In practice I find it better to instantiate objects in the view function. For instance, in a PUT resource, I prefer to instantiate the existing item from DB then update it with new data. In this case it is better to have the new data as dict than object.

There may not be a single truth, here, it could be a matter of opinion, but while the idea of having the object instantiated in the decorator and passed to the view is appealing, it might be a bit of an abusive shortcut.


I realize this answer is of the "no idea but you shouldn't do it anyway" type. Just saying maybe you shouldn't struggle to achieve this.

This said, I'd be surprised if it worked with non-list / non-nested inputs and I'd wonder why it doesn't work specifically in this case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文