如何在Flask中允许使用HTTP方法“PUT”和“DELETE”?

3

我正在学习Python,并尝试使用以下方法执行PUT和DELETE操作:

import gamerocket
from flask import Flask, request, render_template
app = Flask(__name__)

gamerocket.Configuration.configure(gamerocket.Environment.Development,
                                apiKey = "my_apiKey",
                                secretKey = "my_secretKey")

@app.route("/update_player", methods = ["PUT"])
def update_player():
    result = gamerocket.Player.update(
        "a_player_id",
        {
            "name" : "bob_update",
            "emailHash" : "update@test.com",
            "totalPointsAchievement" : 1
        }
    )

if result.is_success:
    return "<h1>Success! " + result.player.id + " " + result.player.name +   "</h1>"
else:
    return "<h1>Error " + result.error + ": " + result.error_description

if __name__ == '__main__':
app.run(debug=True)

但是我收到了一个HTTP 405错误

请求的URL不允许该方法。

你能帮我吗?

编辑:以下是我调用该方法的方式:

class PlayerGateway(object):
    def update(self, player_id, params={}):
    response = self.config.http().put("/players/" + player_id, params)
    if "player" in response:
        return SuccessfulResult({"player": Player(self.gateway,response["player"])})
    elif "error" in response:
        return ErrorResult(response)
    else:
        pass

在Http中的下一步:

class Http(object):
    def put(self, path, params={}):
        return self.__http_do("PUT", path, params)
    def delete(self, path, params={}):
        return self.__http_do("DELETE", path, params)

    def __http_do(self, http_verb, path, params):

        http_strategy = self.config.http_strategy()

        full_path = self.environment.base_url + "/api/" + self.config.api_version() + path
        params['signature'] = self.config.crypto().sign(http_verb, full_path, params,
                              self.config.secretKey)

        params = self.config.sort_dict(params)

        request_body = urlencode(params) if params !={} else ''

        if http_verb == "GET":
            full_path += "?" + request_body
        elif http_verb == "DELETE":
            full_path += "?" + request_body

        status, response_body = http_strategy.http_do(http_verb, full_path, 
                            self.__headers(),request_body)

        if Http.is_error_status(status):
            Http.raise_exception_from_status(status)
        else:
            if len(response_body.strip()) == 0:
                return {}
            else:
                return json.loads(response_body)

    def __headers(self):
        return {
            "Accept" : "application/json",
            "Content-type" : "application/x-www-form-urlencoded",
            "User-Agent" : "Gamerocket Python " + version.Version,
            "X-ApiVersion" : gamerocket.configuration.Configuration.api_version()
        }

而且要确定请求策略:

import requests

class RequestsStrategy(object):
    def __init__(self, config, environment):
        self.config = config
        self.environment = environment

    def http_do(self, http_verb, path, headers, request_body):

        response = self.__request_function(http_verb)(
            path,
            headers = headers,
            data = request_body,
            verify = self.environment.ssl_certificate,
        )

        return [response.status_code, response.text]

    def __request_function(self, method):
        if method == "GET":
            return requests.get
        elif method == "POST":
            return requests.post
        elif method == "PUT":
            return requests.put
        elif method == "DELETE":
            return requests.delete

请看这里:http://flask.pocoo.org/snippets/38/ - acj
1
你是怎么调用这个方法的?从快速查看来看,一切似乎都没问题,那么也许你正在尝试通过GET访问它,而不是PUT? - Rapolas K.
我刚刚编辑了问题,并附上了调用方法。 - Nincha
1个回答

1
我尚未尝试运行您的代码,但我认为我可以看出正在发生的事情。
class PlayerGateway(object):
    def update(self, player_id, params={}):
    response = self.config.http().put("/players/" + player_id, params)
    if "player" in response:
        return SuccessfulResult({"player": Player(self.gateway,response["player"])})
    elif "error" in response:
        return ErrorResult(response)
    else:
        pass

你正在调用路由 base_url/api/version/players/,使用该调用代码。
然而,你正在注册路由“/update_player”,使用PUT方法。
没有看到你的Flask应用程序的其余部分,我无法确定是否存在问题,但你必须定义每个根目录允许的方法。 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接