I'm developing a web app in Flask. At that time, I thought about how to deal with the problem that CSS is cached in the Web browser.
When linking CSS in HTML, you may have manually added the modification date and version, such as style.css? V = 12
. However, since I am using Python, I would like you to solve this automatically.
After searching, the model answer is that you should rewrite the url_for as follows.
app.py
@app.context_processor
def override_url_for():
return dict(url_for=dated_url_for)
def dated_url_for(endpoint, **values):
if endpoint == 'static':
filename = values.get('filename', None)
if filename:
file_path = os.path.join(app.root_path,
endpoint, filename)
values['q'] = int(os.stat(file_path).st_mtime)
return url_for(endpoint, **values)
And in the template, link as follows
hoge.html
<link rel= "stylesheet" type= "text/css"
href= "{{ url_for('static',filename='style.css') }}">
A technique that overwrites the url_for in the context processor. It is a technique to add the file modification date when static is specified for the endpoint.
By the way, the following is the English page of the original story. It was introduced in other blogs in Japan as a reference. (Reference) https://stackoverflow.com/questions/21714653/flask-css-not-updating
However, as I always think, using url_for is long when you just write a static link. It's a hassle. In Flask, static files are placed under / static
by default, so the path to place CSS should already be decided. In other words, using url_for when you just embed a static file feels quite annoying.
So, I cut corners and thought about the following method.
The first way is to use a filter.
app.py
@app.template_filter('staticfile')
def staticfile_filter(fname):
path = os.path.join(app.root_path, 'static', fname)
mtime = str(int(os.stat(path).st_mtime))
return '/static/' + fname + '?v=' + str(mtime)
Write the template as follows.
hoge.html
<link rel="stylesheet" type="text/css"
href="{{ 'style.css' | staticfile }}">
It was much more elegant than the model answer.
However, the problem with this method is that the template engine caches the HTML, so the cache is not updated instantly. Still, it looks like style.css? V = xxx.
After all, I thought about chewing the model answer and using context_processor.
app.py
@app.context_processor
def add_staticfile():
def staticfile_cp(fname):
path = os.path.join(app.root_path, 'static', fname)
mtime = str(int(os.stat(path).st_mtime))
return '/static/' + fname + '?v=' + str(mtime)
return dict(staticfile=staticfile_cp)
And the template looks like this
hoge.html
<link rel="stylesheet" type="text/css"
href="{{ staticfile('style.css') }}">
In this case, it is not cached, the value is reflected instantly, and it does not look so bad, is it okay?
The combination of Flask + jinja2 is easy to use and easy to expand, so I like it. The findings obtained are as follows.
--If you use a filter, the contents will not be rewritten unless you change the template. --Using the context processor, the value is always up-to-date because it is executed before the embedding process in the template.
Recommended Posts