Skip to main content
 首页 » 编程设计

python之使用 Webargs Flaskparser 验证 URL 路径中的可变参数和查询参数

2024年08月15日50zengkefu

我正在尝试验证发送到我的 api 的所有数据。我的 url 结构中包含一个变量,/api/v2/users/<string:username>/collections/ ,以及实际的查询字符串参数,所有这些都需要通过验证。

完整的 url 如下所示: https://127.0.0.1:5000/api/v2/users/<string:username>/collections/?page=5&per_page=10

需要验证的两个变量是:username page , 和 per_page .简单的解决方案是更改我的 url 结构,但我想知道是否有可能完成我需要的并保持我目前拥有的简单性,而无需在我的资源类中添加额外的验证。如果可能的话,你是怎么做到的?

class UserCollections(Resource): 
    @use_args({ 
        'username': fields.Str( 
            required=True, 
            validate=username_length, 
            error_messages=dict( 
                required='Username is required.', 
                validator_failed='Username can be between 3 and 25 characters.', 
            ) 
        ), 
        'page': fields.Int( 
            #required=True, 
            missing=1, 
            validate=feed_minmax_pages, 
            error_messages=dict( 
                validator_failed='Maximum number of pages reached.', 
            ) 
        ), 
        'per_page': fields.Int( 
            #required=True, 
            missing=5, 
            validate=validate.Range(min=5,max=25), 
            error_messages=dict( 
                validator_failed='Test number of pages reached.', 
            ) 
        ), 
    }, locations=('query',)) 
 
    def get(self, args, username): 
        print(args) 
        print(username) 
 
        return default_schema( 
            data={}, 
            http_status=200 
        ) 

当我运行代码时,我收到了 username 的验证错误因为它不存在于 args 中。

请您参考如下方法:

在四处寻找一段时间后,我找到了解决方案,我现在在 webargs flaskparser documentation 中看到了它

除了其他 use_args location 之外,这可以很容易地使用参数中的参数。看起来请求方法函数get , post等仍然需要您传入该 url 变量。在我的例子中是 <username> .

class UserCollections(Resource): 
    @use_args({ 
        'username': fields.Str( 
            location='view_args', 
            required=True, 
            validate=username_length, 
            error_messages=dict( 
                required='Username is required.', 
                validator_failed='Username can be between 3 and 25 characters.', 
            ) 
        ), 
        'page': fields.Int( 
            location='query', 
            missing=1, 
            validate=feed_minmax_pages, 
            error_messages=dict( 
                validator_failed='Maximum number of pages reached.', 
            ) 
        ), 
        'per_page': fields.Int( 
            location='query', 
            missing=5, 
            validate=validate.Range(min=5,max=25), 
            error_messages=dict( 
                validator_failed='Test number of pages reached.', 
            ) 
        ), 
    }) 
 
    def get(self, args, username): 
        print(args) # access with args['username'] 
        print(username) # would be nice to not have a second of the same var 
 
        return default_schema( 
            data={}, 
            http_status=200 
        )