簡體   English   中英

Flask-Restx Api.model(strict=True) 允許未指定的參數

[英]Flask-Restx Api.model(strict=True) allowing unspecified params

我有一個簡單的用戶資源,它帶有一個 put 方法來更新除用戶密碼之外的所有用戶信息。 根據 Flask-Restx 文檔,當 model 將嚴格和驗證參數設置為 true 時,如果在請求中提供了未指定的參數,則會引發驗證錯誤。 但是,這似乎對我不起作用。

Model定義:

from flask_restx import Namespace, Resource, fields, marshal

users_ns = Namespace("users")

user = users_ns.model(
    "user",
    {
        "user_name": fields.String(example="some_user", required=True),
        "email": fields.String(example="some.user@email", required=True),
        "is_admin": fields.Boolean(example="False"),
        "is_deactivated": fields.Boolean(example="False"),
        "created_date": fields.DateTime(example="2020-12-01T01:59:39.297904"),
        "last_modified_date": fields.DateTime(example="2020-12-01T01:59:39.297904"),
        "uri": fields.Url("api.user"),
    },
    strict=True,
)

user_post = users_ns.inherit(
    "user_post", user, {"password": fields.String(required=True)}
) # Used for when 

資源和方法定義:

from api.models import Users

class User(Resource):
    @users_ns.marshal_with(user)
    @users_ns.expect(user, validate=True)
    def put(self, id):
        """
        Update a specified user.
        """

        user = Users.query.get_or_404(id)
        body = request.get_json()

        user.update(body)

        return user

失敗的測試:

def test_update_user_invalid_password_param(self, client, db):
        """ User endpoint should return 400 when user attempts to pass password param to update. """
        data = {
            "user_name": "some_user",
            "email": "some.user@email.com",
            "password": "newpassword",
        }

        response = client.put(url_for("api.user", id=1), json=data)

        assert response.status_code == 400

此處的 response.status_code 為 200,因為在請求正文中傳遞的未指定參數不會引發驗證錯誤。

我是否不正確地使用了嚴格的參數? 我是否誤解了嚴格的行為?

更新:我添加了對來自 Flask-RestX 存儲庫的嚴格 model 參數的測試(可以在此處找到)以獲取有關預期行為的更多上下文:

def test_api_payload_strict_verification(self, app, client):
        api = restx.Api(app, validate=True)
        ns = restx.Namespace("apples")
        api.add_namespace(ns)

        fields = ns.model(
            "Person",
            {
                "name": restx.fields.String(required=True),
                "age": restx.fields.Integer,
                "birthdate": restx.fields.DateTime,
            },
            strict=True,
        )

        @ns.route("/validation/")
        class Payload(restx.Resource):
            payload = None

            @ns.expect(fields)
            def post(self):
                Payload.payload = ns.payload
                return {}

        data = {
            "name": "John Doe",
            "agge": 15,  # typo
        }

        resp = client.post_json("/apples/validation/", data, status=400)
        assert re.match("Additional properties are not allowed \(u*'agge' was unexpected\)", resp["errors"][""])

我通過從 Github 中提取最新版本的 Flask-RESTX 解決了我的問題。 在 2020 年 3 月在 Pypi 上發布 Flask-RESTX 版本 0.2.0 后,模型的嚴格參數被合並(有關更多上下文,請參閱 Flask-RESTX 存儲庫中的已關閉問題)。 我的困惑出現了,因為文檔似乎代表了最新的 state,而不是最新的 Pypi 版本。

自從我談到這個已經有一段時間了,但據我所知,我認為你沒有正確使用嚴格的參數。 這里的文檔中, :param bool strict定義為

:param bool strict: 當模式中沒有提供參數時,驗證應該引發錯誤

但是在您的最后一段代碼中,您正嘗試使用帶有請求正文的字典data進行驗證。

如果我再次記得,對於這類任務,您需要使用(並且正如您所提到的) RequestParser 這里有一個很好的例子——flask——比@api.expect 輸入數據更嚴格?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM