我通过在我的eve-API上执行POST请求将新数据添加到我的数据库中。 由于需要从Python端添加一些数据,我认为我可以使用pre-request event hook添加这些数据。
那么有没有办法在将数据插入数据库之前使用预请求挂钩修改POST请求中包含的数据?我已经了解了如何实现这样的钩子,但是在插入数据库之前没有任何关于如何修改数据的线索。
答案 0 :(得分: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 :(得分:0)
就我而言,如果给定属性包含在数据中,我想复制文档。
我必须使用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属性。然后就可以了。
答案 2 :(得分: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