如何从网址获取Put路由和删除的ID

时间:2018-04-26 21:13:40

标签: python python-3.x api tornado

我正在尝试将所有crud方法放在 python Tornado 框架中的一个处理程序类下。 Post()get()有效,但由于某种原因无法定义 carId 。我可以将api端点的id传递给方法的一种方法是什么。 放置和删除的端点:api/cars/1

  

错误:TypeError:put()缺少1个必需的位置参数:
  ' carId'错误: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()

2 个答案:

答案 0 :(得分:1)

您需要在正则表达式中使用捕获组来告诉Tornado将哪些部分传递给您的方法。在与carId对应的零件周围加上括号:

 (r"/api/cars/([0-9])/?", CarHandler)

请注意,carId将作为字符串传递,因此您可能需要使用carId = int(carId)进行转换。 (另外,除非您的车辆ID只是单个数字,否则您可能需要([0-9]+)

答案 1 :(得分:0)

解释错误: 此路由(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) isn&t; t)。这种路由调用方法如下:self.method();一旦他们期待参数,它将适用于self.get()self.post(),但不能放或删除。您可以修复它将处理程序拆分为两个或将方法定义更改为:

def delete(self, carId=None):
    ...

def put(self, carId=None):
    ...

并添加一些逻辑验证if carId is None: return