Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tornado RESTful PUT处理程序方法未获取请求参数_Python_Rest_Tornado - Fatal编程技术网

Python Tornado RESTful PUT处理程序方法未获取请求参数

Python Tornado RESTful PUT处理程序方法未获取请求参数,python,rest,tornado,Python,Rest,Tornado,我正在尝试对我的RESTful API进行单元测试。以下是我的API: class BaseHandler(tornado.web.RequestHandler): def __init__(self, *args, **kwargs): tornado.web.RequestHandler.__init__(self, *args, **kwargs) self

我正在尝试对我的RESTful API进行单元测试。以下是我的API:


class BaseHandler(tornado.web.RequestHandler):                    
    def __init__(self, *args, **kwargs):                          
        tornado.web.RequestHandler.__init__(self, *args, **kwargs)
        self.log = self.application.log                           
        self.db = self.application.db                             

class ProductHandler(BaseHandler):
    @tornado.web.removeslash
    def put(self, id = None, *args, **kwargs):
        try:
            self.log.info("Handling PUT request")                                                             
            if not id:                                                                                                      
                raise Exception('Object Id Required')                                                                        
            id = { '_id' : id }                                                                                                                            
            new_values = dict()                                                                                             
            name = self.get_argument('name', None)                                                                          
            description = self.get_argument('description', None)                                                            
            if name:                                                                                                        
                new_values['name'] = name                                                                                   
            if description:                                                                                                 
                new_values['description'] = description                                                                     
            self.db.products.update(id, new_values, safe = True)                                                                                                               
        except:
            self.log.error("".join(tb.format_exception(*sys.exc_info())))                                                   
            raise                                                                                                           

 class Application(tornado.web.Application):                         
     def __init__(self, config_path, test = False, *args, **kwargs): 
         handlers = [                                                
             (r"/product/?(.*)", ProductHandler),                    
         ]                                                           
         settings = dict(debug=True)                                 
         tornado.web.Application.__init__(self, handlers, **settings)
         self.log = logging.getLogger(__name__)                      
         self.config = ConfigParser()                                
         self.config.read(config_path)                               
         self.mongo_connection = Connection(                         
             host = self.config.get('mongo','host'),                 
             port = self.config.getint('mongo','port'),              
         )                                                           
         if test:                                                    
             db_name = self.config.get('test', 'mongo.db')           
         else:                                                       
             db_name = self.config.get('mongo', 'db')                
         self.log.debug("Using db:  %s" % db_name)                   
         self.db = self.mongo_connection[db_name]                    

但是,我的问题是:处理程序没有看到名称或描述参数:(


有什么建议吗?

您是否尝试过使用
get
方法来代替?因为根据您测试程序的方式,如果您通过Firefox或Chrome等浏览器进行测试,他们可能可以做到这一点

如果我是你,我会写
get
而不是
put
。因为这样你就可以在浏览器中测试它了

例如,而不是:

def put ...
尝试:

或者实际上在你的:

name = self.get_argument('name', None)                                                                          
description = self.get_argument('description', None) 
为什么
None
存在?根据:

获取参数(名称,默认值=[],strip=True)

如果未提供默认值,则认为该参数是必需的, 如果缺少HTTP 400异常,我们将抛出该异常

因此,在您的情况下,由于您没有提供正确的默认值,因此您的应用程序返回HTTP 400。请忽略默认值!(即)


作为一种解决方法,我在request.body中找到了它们,并手动解析了编码的参数。这有点烦人,但它可以工作


new_values = urlparse.parse_qs(self.request.body)

# values show as lists with only one item
for k in new_values:                             
    new_values[k] = new_values[k][0]             

假设您正在使用jQuery发送此PUT请求:

$.ajax({
    type: "PUT",
    url: "/yourURL",
    data: JSON.stringify({'json':'your json here'),
    dataType: 'json'
})
数据
不应类似于:
数据:{'json':'your json here'},
因为它将自动编码到查询字符串中,需要由parseqs解析

然后在龙卷风中

def put(self, pid):
    d = json.loads(self.request.body)
    print d

如果请求具有正确的内容类型头(application/x-www-form-urlencoded),则put处理程序将解析request.body,例如,如果您使用的是tornado http客户端:

headers = HTTPHeaders({'content-type': 'application/x-www-form-urlencoded'})
http_client.fetch(
      HTTPRequest(url, 'PUT', body=urllib.urlencode(body), headers=headers))

我故意使用put。据我所知,tornado就是这样工作的。而且,我使用get_参数(arg,None),因为我给调用者一个选项来更新产品上的一个或两个字段。你也可以使用
get
!tornado也是这样工作的。你如何测试你的程序?“我给调用者一个选项来更新产品上的一个或两个字段"-您可以获取参数并测试参数是否为
None
,如果没有,则不更新该特定字段。例如
如果name为None:…不更新name
我用于单元测试。想知道您是否可以发布您的测试代码?您的测试代码是否有效?在没有解释为什么无效的情况下对某些内容进行向下投票。我没有我最后把我的参数放在了查询字符串上。我怀疑这与asynchttpclient没有“放”写请求有关。
def put(self, pid):
    d = json.loads(self.request.body)
    print d
headers = HTTPHeaders({'content-type': 'application/x-www-form-urlencoded'})
http_client.fetch(
      HTTPRequest(url, 'PUT', body=urllib.urlencode(body), headers=headers))