bottlepy / bottle

bottle.py is a fast and simple micro-framework for python web-applications.
http://bottlepy.org/
MIT License
8.37k stars 1.46k forks source link

difference between request.url_args and request.query #1153

Closed oz123 closed 5 years ago

oz123 commented 5 years ago

What is the difference between the two if any?

Sometime the information passed through is in url_args and sometime in query. See this debugging session for example:

> bottle.py(1134)__call__()
-> return self.wsgi(environ, start_response)
(Pdb) id(request)
139932581456200
(Pdb) request.url_args
{'filepath': 'imgs/logo.svg'}
(Pdb) l
1129    
1130        def __call__(self, environ, start_response):
1131            """ Each instance of :class:'Bottle' is a WSGI application. """
1132    
1133            import pdb; pdb.set_trace()
1134 ->         return self.wsgi(environ, start_response)
1135    
1136        def __enter__(self):
1137            """ Use this application as default for all module-level shortcuts. """
1138            default_app.push(self)
1139            return self
(Pdb) c
> app/views.py(192)main()
-> if url is None:
(Pdb) request.url_args
{}
(Pdb) id(request)
139932581456200
(Pdb) request.query
<tiny.bottle.FormsDict object at 0x7f4494e1ec50>
(Pdb) [f for f in request.query.items()]
[('foo', 'bar')]

So at first the query string is in url_args and later it is in query. Also url_args is now empty. I have checked also that in both break points the request object is the same object.

Can you explain what is going on here?

defnull commented 5 years ago

These are two completely different things. url_args contains values extracted from dynamic parts in the request path. It's populated by the router that matches request path against bottle routes. It is therefor only available after routing. query is the parsed request query string (the part after the ?). The query string is never in url_args.

For example, if the route is defined by @route('/hello/<name>') and a request is made for /hello/world?some=query then request.url_args will be {'name':'world'} and request.query will be {'some':'query'}.

oz123 commented 5 years ago

@defnull thanks for the quick response.