Python-Eve:使用预请求事件挂钩在插入数据库之前修改数据

问题描述 投票:4回答:3

我通过在我的eve-API上执行POST请求,将新数据添加到我的数据库中。由于需要从Python端添加一些数据,我认为我可以使用pre-request event hook添加这些数据。

那么有没有办法在将数据插入数据库之前使用预请求挂钩修改POST请求中包含的数据?我已经了解了如何实现这样的钩子,但是在插入数据库之前没有任何关于如何修改数据的线索。

python mongodb eve
3个回答
5
投票

你可能想看看database hooks,特别是在insert hooks

当POST请求命中API并且新项目即将存储在数据库中时,会触发这些通风口:

on_insert用于每个资源端点。

on_insert_<resource_name>用于特定资源端点。

回调函数可以挂钩到这些事件中,以任意添加新字段或编辑现有字段。

在下面的代码中:

def before_insert(resource_name, documents):
    if resource_name == 'myresource':
        for document in documents:
            document['field'] = 'value'

app = Eve()
app.on_insert += before_insert

app.run()

每当POST命中API时,都会调用before_insert函数。该函数为每个文档更新field1。由于在将有效负载发送到数据库之前调用此回调,因此更改将持久保存到数据库。

一个有趣的选择是:

def before_insert(resource_name, documents):
    for document in documents:
        document['field'] = 'value'

app = Eve()
app.on_insert_myresource += before_insert

app.run()

在回调中,我们不再测试端点名称了。这是因为我们将回调挂钩到on_insert_myresoure事件,因此只有在myresource端点上执行POST请求时才会调用该函数。更好地分离关注点,代码更简单,并且还提高了性能,因为回调不会受到所有API插入的影响。注意,最终你可以将多个回调挂钩到同一个事件(因此使用加法运算符+=)。


1
投票

在我的情况下,如果给定的属性在数据中,我想复制文档。

我必须使用pre_POST事件挂钩来做到这一点。

def pre_notifications(request):
    data = json.loads(request.get_data())
    if 'payload' in data and 'condition' in data:
        notification = data['payload']
        documents = []
        users = app.data.pymongo().db.users.find()
        for user in users:
            copy_notification = copy(notification)
            copy_notification['user_email'] = user['user_email']
            documents.append(copy_notification)
        request._cached_data = json.dumps(documents).encode('utf-8')

首先,我试图替换request.data但它不起作用。对代码进行一些搜索我找到了_cached_data属性。然后它工作。


0
投票

只是为了补充@Gustavo的答案(我不能在他的回答中留下评论)。您可以在不序列化数据的情况下更新request._cached_json属性。

用他的例子:

def pre_notifications(request):
    data = json.loads(request.get_data())
    if 'payload' in data and 'condition' in data:
        notification = data['payload']
        documents = []
        users = app.data.pymongo().db.users.find()
        for user in users:
            copy_notification = copy(notification)
            copy_notification['user_email'] = user['user_email']
            documents.append(copy_notification)
        request._cached_json = documents
© www.soinside.com 2019 - 2024. All rights reserved.