如何从 url 获取 Put 路由和 Delete 的 ID
How to get ID from url for Put route and Delete
我试图将所有 crud 方法放在 python Tornado 框架中的一个处理程序 class 下。 Post()
和 get()
有效,但由于某些原因无法定义 carId。我可以将 api 端点的 ID 传递给该方法的一种方法是什么。
放置和删除的端点:api/cars/1
Error: TypeError: put() missing 1 required positional argument:
'carId' ERROR:tornado.access:500 PUT /api/cars/1 (::1) 0.50ms
方法:
# Delete method that deletes data specified by HTTP client from database
def delete(self, carId):
try:
data = json.loads(self.request.body)
print(data)
print("Deleting Car")
id = data["id"]
if not carId:
return self.write({"success": False})
if not len(id):
return self.write({"success": False})
c.execute(
"DELETE FROM cars WHERE id=?",(carId))
self.write({"success": 200})
except:
self.write({"success": False})
conn.commit()
# Put route to edit an entity in DB.
def put(self, carId):
try:
data = json.loads(self.request.body)
print(data)
print("Updating Cars table")
id = data["id"]
make = data["make"]
model = data["model"]
if not make or not model or not carId:
return self.write({"success": False})
if not len(make) or not len(model):
return self.write({"success": False})
c.execute(
"UPDATE cars SET make=?, model=? WHERE id=?",(make, model, id))
self.write({"success": 200})
except:
self.write({"success": False})
conn.commit()
def verifyDatabase():
try:
c.execute('SELECT * FROM cars')
print('Table already exists')
except:
print('Creating table \'cars\'')
c.execute('CREATE TABLE cars (\
id integer primary key,\
make text,\
model text)')
print('Successfully created table \'cars\'')
conn.commit()
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r"/", MainHandler),
(r"/api/cars/?", CarHandler),
(r"/api/cars/[0-9]/?", CarHandler)
]
tornado.web.Application.__init__(self, handlers)
def main():
# Verify the database exists and has the correct layout
verifyDatabase()
app = Application()
app.listen(80)
IOLoop.instance().start()
conn.close()
if __name__ == '__main__':
main()
您需要在正则表达式中使用 捕获组 来告诉 Tornado 将哪些部分传递给您的方法。在 carId
:
对应的部分加上括号
(r"/api/cars/([0-9])/?", CarHandler)
请注意,carId
将作为字符串传递,因此您可能需要将其转换为 carId = int(carId)
。 (此外,除非您的汽车 ID 只能是个位数,否则您可能需要 ([0-9]+)
)
解释错误:
这条路线 (r"/api/cars/?", CarHandler)
指向 CarHandler 但它没有向处理程序的方法传递任何参数。我相信 get 和 post 方法是这样定义的:def get(self):
,所以它们真的不需要任何参数;另一方面,put 和 delete 方法定义为 def put(self, carId):
,因此它们需要获取参数。出于这个原因,你得到了错误:
Error: TypeError: put() missing 1 required positional argument:
同样,(r"/api/cars/[0-9]/?", CarHandler)
也没有传递参数。
修复路由错误:
首先,正如另一位成员所解释的那样,您需要修复 (r"/api/cars/[0-9]/?", CarHandler)
才能将参数传递给您的方法。您只需在路线中输入 (
和 )
即可。应该是这样的:(r"/api/cars/([0-9])/?", CarHandler)
.
修复方法定义错误:
你可以看到,即使你按照我说的去做,你可能仍然会遇到同样的错误。问题是所有路由都指向处理程序中的所有方法。因此处理程序的方法应该具有相同的方法签名,或者它们应该能够以相同的方式被调用。
这一点有点棘手。 PUT 和 DELETE 方法期望获得 carId,但并非所有路由都传递 carId 作为参数((r"/api/cars/?", CarHandler)
不是)。这个路由调用方法是这样的:self.method()
;它适用于 self.get()
或 self.post()
,但一旦他们期待争论,就无法放置或删除。您可以修复它,将您的处理程序一分为二或将您的方法定义更改为:
def delete(self, carId=None):
...
def put(self, carId=None):
...
并添加一些逻辑验证作为 if carId is None: return
我试图将所有 crud 方法放在 python Tornado 框架中的一个处理程序 class 下。 Post()
和 get()
有效,但由于某些原因无法定义 carId。我可以将 api 端点的 ID 传递给该方法的一种方法是什么。
放置和删除的端点:api/cars/1
Error: TypeError: put() missing 1 required positional argument:
'carId' ERROR:tornado.access:500 PUT /api/cars/1 (::1) 0.50ms
方法:
# Delete method that deletes data specified by HTTP client from database
def delete(self, carId):
try:
data = json.loads(self.request.body)
print(data)
print("Deleting Car")
id = data["id"]
if not carId:
return self.write({"success": False})
if not len(id):
return self.write({"success": False})
c.execute(
"DELETE FROM cars WHERE id=?",(carId))
self.write({"success": 200})
except:
self.write({"success": False})
conn.commit()
# Put route to edit an entity in DB.
def put(self, carId):
try:
data = json.loads(self.request.body)
print(data)
print("Updating Cars table")
id = data["id"]
make = data["make"]
model = data["model"]
if not make or not model or not carId:
return self.write({"success": False})
if not len(make) or not len(model):
return self.write({"success": False})
c.execute(
"UPDATE cars SET make=?, model=? WHERE id=?",(make, model, id))
self.write({"success": 200})
except:
self.write({"success": False})
conn.commit()
def verifyDatabase():
try:
c.execute('SELECT * FROM cars')
print('Table already exists')
except:
print('Creating table \'cars\'')
c.execute('CREATE TABLE cars (\
id integer primary key,\
make text,\
model text)')
print('Successfully created table \'cars\'')
conn.commit()
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r"/", MainHandler),
(r"/api/cars/?", CarHandler),
(r"/api/cars/[0-9]/?", CarHandler)
]
tornado.web.Application.__init__(self, handlers)
def main():
# Verify the database exists and has the correct layout
verifyDatabase()
app = Application()
app.listen(80)
IOLoop.instance().start()
conn.close()
if __name__ == '__main__':
main()
您需要在正则表达式中使用 捕获组 来告诉 Tornado 将哪些部分传递给您的方法。在 carId
:
(r"/api/cars/([0-9])/?", CarHandler)
请注意,carId
将作为字符串传递,因此您可能需要将其转换为 carId = int(carId)
。 (此外,除非您的汽车 ID 只能是个位数,否则您可能需要 ([0-9]+)
)
解释错误:
这条路线 (r"/api/cars/?", CarHandler)
指向 CarHandler 但它没有向处理程序的方法传递任何参数。我相信 get 和 post 方法是这样定义的:def get(self):
,所以它们真的不需要任何参数;另一方面,put 和 delete 方法定义为 def put(self, carId):
,因此它们需要获取参数。出于这个原因,你得到了错误:
Error: TypeError: put() missing 1 required positional argument:
同样,(r"/api/cars/[0-9]/?", CarHandler)
也没有传递参数。
修复路由错误:
首先,正如另一位成员所解释的那样,您需要修复 (r"/api/cars/[0-9]/?", CarHandler)
才能将参数传递给您的方法。您只需在路线中输入 (
和 )
即可。应该是这样的:(r"/api/cars/([0-9])/?", CarHandler)
.
修复方法定义错误: 你可以看到,即使你按照我说的去做,你可能仍然会遇到同样的错误。问题是所有路由都指向处理程序中的所有方法。因此处理程序的方法应该具有相同的方法签名,或者它们应该能够以相同的方式被调用。
这一点有点棘手。 PUT 和 DELETE 方法期望获得 carId,但并非所有路由都传递 carId 作为参数((r"/api/cars/?", CarHandler)
不是)。这个路由调用方法是这样的:self.method()
;它适用于 self.get()
或 self.post()
,但一旦他们期待争论,就无法放置或删除。您可以修复它,将您的处理程序一分为二或将您的方法定义更改为:
def delete(self, carId=None):
...
def put(self, carId=None):
...
并添加一些逻辑验证作为 if carId is None: return