Python Eve: сбой предварительного условия 412 на PATCH

У меня есть приложение Python Eve со следующим соответствующим кодом:

def handle_user_update(request, lookup):
if request and request.data:
    data = json.loads(request.data)
    users = app.data.driver.db['users']
    user = users.find_one(ObjectId(lookup['_id']))
    if user and user['activation_code'] == data['activation_code']:
        app.data.update('users', ObjectId(lookup['_id']), {'active':True})
    else:
        abort(403)

app = Eve()

if __name__ == '__main__':
    app.on_pre_PATCH_users += handle_user_update
    app.run(host='0.0.0.0')

Поле определено:

'active': {
    'type': 'boolean',
    'readonly': True,
    'default': False
},
'activation_code': {
    'type': 'string',
    'readonly': True
}

Я отправляю запрос PATCH:

If-Match:       c8f9351a7527f8aa1db191fe85017df1dbca961f
{"activation_code": "8f775627d1144dbd8367778e8680ed58"}

Я получил If-Match из ETag запроса GET, отправленного непосредственно перед этим PATCH. Метод app.data.update выполняется, и данные обновляются, как и ожидалось, однако я получаю ответ 412 PRECONDITION FAILED. Почему? Что мне нужно сделать, чтобы получить 200 OK?


person Stefan D    schedule 26.11.2014    source источник


Ответы (1)


Причина, по которой ваш users документ обновляется, заключается в том, что вы подключаете свою функцию обратного вызова к Pre -Событие запроса. Они возникают каждый раз при получении запроса и перед его обработкой. В вашем случае вы, вероятно, захотите привязать свой обратный вызов к событию базы данных. События базы данных возникают только в том случае, если запрос был проверен и принят непосредственно перед отправкой документа в базу данных. В вашем случае я бы подключил свою функцию к on_update, которая запускается по подтвержденному запросу PATCH. Это помешает вашему коду воздействовать на базу данных, если первоначальный запрос будет отклонен, чего вы, вероятно, не хотите.

По той причине, почему 412 PRECONDITION FAILED поднимается хорошо... на PATCH запросы, которые возвращаются только в том случае, если ETag не совпадают, поэтому убедитесь, что вы предоставляете правильный. И на какой ты версии Евы?

ОБНОВЛЕНИЕ В версии 0.4, если вы users также являетесь целью запроса, то ETag изменяется, как только вы выполняете пользовательскую запись (изменение представления документа), чтобы это объяснялось, пока вы получаете 412 позже.

person Nicola Iarocci    schedule 26.11.2014
comment
Спасибо за ответ, я запускаю Eve-0.4. Я уверен, что ETag совпадает, поскольку я скопировал его из ответа GET. Могу ли я по-прежнему подключаться к событию базы данных, даже если мое поле определено как доступное только для чтения? Вот почему я использую событие предварительного запроса. - person Stefan D; 26.11.2014
comment
О да, readonly применяется только к данным, поступающим из полезной нагрузки запроса. Поле не предназначено только для чтения в самой базе данных, поэтому вы можете обновлять его по своему усмотрению. - person Nicola Iarocci; 26.11.2014
comment
Я обновил свой ответ, указав вероятную причину, по которой вы получаете 412 в версии 0.4. - person Nicola Iarocci; 26.11.2014
comment
Спасибо. В итоге я изменил свой дизайн, удалив «только для чтения» из полей и принудительно проверив вставку и обновление записи БД. - person Stefan D; 27.11.2014