简体   繁体   中英

Using self.render() in a StaticFileHandler

I'm trying to extend StaticFileHandler in such a way that I can process file requests but call self.render(filename, **kwargs) on the file to actually serve it to the client. (Yes, I realize that at that point it's no longer a static file per se).

Here's the code I'm trying to run:

class MustacheFileHandler(tornado.web.StaticFileHandler):
    def get(self, filename):
        self.render(_STATIC_ROOT_ + '/' + path.split('/')[len(path.split('/'))-2], userLoginStatus='you are logged out!')

# ...
class Application(tornado.web.Application):
    def __init__(self, **overrides):
         handlers = [(r'/(.*)', MustacheFileHandler, {'path' : _STATIC_ROOT_})]
# ...

... Where _STATIC_ROOT_ is a variable included in my server's config file loaded on startup.

The issue I've got is, whenever I try to do a GET on a file I know exists on the server, I get the following error:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1332, in _execute
    result = method(*self.path_args, **self.path_kwargs)
  File "myfile.py", line 173, in get
    self.render(_STATIC_ROOT_ + '/' + path.split('/')[len(path.split('/'))-2], userLoginStatus='you are logged out!')
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 747, in render
    self.finish(html)
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 877, in finish
    self.set_etag_header()
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1257, in set_etag_header
    etag = self.compute_etag()
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 2185, in compute_etag
    version_hash = self._get_cached_version(self.absolute_path)
AttributeError: 'MustacheFileHandler' object has no attribute 'absolute_path'

I'm not sure what's causing this error or how I can handle it.

Why are you using StaticFileHandler if the response is not static? This is likely to break assumptions built into the class.

StaticFileHandler is designed to be subclassed in limited ways as described in its documentation . In particular, subclasses should not override get() , and attempting to do so results in the error you're seeing.

If you want to use the Tornado template engine as a kind of preprocessor of the files on disk, you could try to do this by overriding both get_content and get_content_size , and making them call self.render_string() (also consider that if your templates are not individually self-contained you'll need to change get_content_version to take all dependencies into account). However, this requires messy caching to avoid rendering the template multiple times. It's probably better to either A) Render the templates on the fly with an ordinary RequestHandler. or B) Write a little script to render all your templates, write them to disk, and serve the results as actual static files.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM