Flask does not load CSS file..? - python

So the problem I'm having is that my web app only sometimes loads the css file and it uses the same css file data that was loaded even if I make edits to the css file and even when I delete the file. I have no clue what's going on. I have noticed that when it does load the css correctly the following message is displayed:
127.0.0.1 - - [08/Jun/2015 14:46:19] "GET /static/style.css HTTP/1.1" 200
My style.css file is under a folder named static and in my html file I have
<link type='text/css' href='{{ url_for('static', filename='style.css') }}' rel='stylesheet'>

Flask sets cache control headers on static resources, and your browser will cache those files up to 12 hours.
Your options are:
Set the SEND_FILE_MAX_AGE_DEFAULT configuration directive to a shorter value; it is set to 43200 but you can set it to 0 if you really want to.
Add a cache buster query parameter to your static URLs; if your static URLs end with ?<somerandomvalue> your browser will reload the resource if that random value ever changes. You could do this by hand each time or you can use this Flask snippet to override the url_for() function to add such a value for you based on the file modification time.
Use an incognito browser window (private browsing mode in other browsers) to force your browser to ignore the cache for a specific session. Each time you open a new incognito tab or window, the cache should be invalidated for that session.

Please use ctrl + f5
because when you use simple refresh it shows data from cache but when you do ctrl + f5 it render new data

I guess it's because of the fact that your browser catches CSS files. In fact, there is no way for browser to detect your changes unless you refresh your page manually by pressing Ctrl+F5 and force browser to flush the resources.
Update 1:
The only One way to fix this is to add a randomly generated suffix to your CSS/JavaScript files and change those values whenever you make a change to your files. This way, the browser catches the latest CSS file and ignores the previous files.

Ctrl+Shift+R to refresh the page works well.

Related

Django admin site downloading style-sheets but not displayed as styled

I have set up a basic Django system and am testing out the admin app. The admin screen displays with raw styles and not the pretty ones shown in the tutorials and specified in the style-sheets.
Following several other questions, I found this is a common problem caused because Django doesn't normally serve static files. However, it does if DEBUG is switched on and I do have debug switched on. I followed all of the suggestions in the answers anyway to collect static files, etc.
If I enter the static file URLs directly they get downloaded and I can see the files in the developer mode of the browser (both Chrome and Edge). So I think the static files are being served.
Furthermore, if I save the page using the browser, it saves all of the static files and then if I open the main page it is shown with the correct styles. So the styles are working.
So it would seem to me that the files are being served and the browser is getting them and it can render them (from a saved file) but it somehow isn't working when served from Django.
Can anyone tell me what is going on?
EDIT:
Here is a strange thing: if, using the Chrome developer tool, I select the base.css file, click somewhere in the text of the CSS (say at the end of a line) and then add a space, suddenly the page appears correctly.
If I then do refresh the page it goes back to unstyled again.
EDIT 2:
I saw a recommendation to install the Whitenoise app to serve static file so I went ahead and did it. I turned off debug and presto! the styles appear. Turning on debug (so I presume django serves the files) and the styles go away. I saved both sites to the file system and compared the directories using a compare tool. There was no difference.
I'm not calling this an answer as the question is:
Why?
Also, I can't have debug on and get styles.

Why does my Flask app not render CSS if I don't clear my cache?

I've been using Flask and have linked the html I'm rendering to a css stylesheet. I've noticed that whenever I update my CSS code, I have to clear the cache in order to get it to update on the webpage. How can I fix this?
I assume you are loading your CSS files with something like:
{{ url_for('static', filename='some/file.css') }}
For this to refresh immediately in development, you should set the following config var to -1:
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = -1
As #Matvei states, this issue is more to do with your browser. To visualise this, open the dev tools, go to the Network tab and highlight the specific CSS file. Then in the section on the right look for the following line under Headers -> Response Headers:
Cache-Control: public, max-age=-1
If the setting has been applied correctly this should show -1. If it shows anything else you need to refresh that specific file, until it does show -1, possibly having to clear your cache. This is because the browser makes the choice of whether to reload the file based on the Cache-Control header.
See my similar answer on this with screencaps and links to the docs.
tldr: Refresh the page with Ctrl-F5 (or whatever your keyboard shortcut is for a hard refresh).
Full Answer:
The issue (if you want to call it that) is with your browser, not Flask.
To improve speed, browsers cache data. In your case, your browser is caching the CSS for your web pages. Your browser doesn't know when you update the CSS, which is why you have to clear the cache.
Even if there was a way of disabling this, I wouldn't. Without caching, web browsing would be significantly slower.
Instead of clearing your entire cache, you can do a hard refresh. That will tell the browser to reload all data (including CSS) directly from the server. In Firefox, the shortcut is Ctrl F5.
More info here: https://humaan.com/blog/clear-your-browser-cache-a-quick-guide/

CSS not being applied in Flask app

I am using flask and Jinja templates. None of my CSS is being applied, except for bootstrap which is being downloaded from an external host.
Here is the line in my base template for my own stylesheet:
<link rel=”stylesheet” type=”text/css” href="{{ url_for('static', filename='style/stylesheet.css') }}">
And then when I open the page in chrome I can follow the link, and it opens up the file successfully. However when I look in the frames I cannot see my stylesheet under the stylesheets section:
Here is the request from the server: GET /static/style/stylesheet.css HTTP/1.1" 200 -
It looks likes it's not being recognized as a css file ? I'm not great with web stuff so hopefully this is something simple.
I have no idea what was happening here. This issue has been ongoing for days.
To fix it I simply copied the line that loads the CSS, saved my project, pasted it back in, and ran the server. Mass confusion.
For anyone else still having issues with this I found this that suggests the CSS is not being "hard refreshed".
I fixed this issue on my Mac in Chrome by holding down both ⌘ Cmd+⇧ Shift and pressing R.

Serve Static Pages from S3 using Django

I'm planning to build a Django app to generate and later server static pages (probably stored on S3). When users visit a url like mysite.com/static-pages/12345 the static file in my S3 bucket named 12345.html should be served. That static file might be the static html page of a blog page my site has generated for the user, for example.
This is different from including static resources like CSS/Javascript files on a page that is rendered as a Django template since I already know how to use Django templates and SQL databases - what's unfamiliar to me is that my "data" is now a file on S3 rather than an entry in a database AND that I don't actually need to use a template.
How exactly can I retrieve the requested data (i.e. a static page) and return it to the user? I'd like to minimize performance penalties within reason, although of course it would be fastest if users directly requested their static pages from S3 (I don't want them to do this)".
A few additional questions:
I've read elsewhere about a django flatpages app which stores html pages in a database, but it seems like static html pages are best stored on a filesystem like S3, no?
Is there a way to have the request come in to my Django application and have S3 serve the file directly while making it appear to have come from my application (i.e. the browser url still says mysite.com/static-pages/12345, but the page did not go through my Django server)?
Thanks very much!
Amazon S3 doesn't support URL rewriting (it's not a webserver), so you're going to have no choice but to proxy the requests to a web server or service that can rewrite the urls for you.
You could use a web server you control and follow the instructions here to have apache rewrite the URLs, but that seems somewhat wasteful when the whole point is loading a static website.
Alternatively, I have a solution that might work if you want to stay purely in S3:
You have the option to specify an HTML document that will be returned to the user's browser in the case of 404 - the error document. You could create a tiny HTML page that checked to the current URL, and simply changed window.location to go to "rewritten" url without the .html extension:
<html>
<script>
var slash = window.location.lastIndexOf("/");
var dot = window.location.lastIndexOf(".");
if (slash < dot) && (dot != -1) {
window.location = window.location + ".html";
}
</script>
</html>
Obviously you'd want to make it more robust, but you get the idea.
The downside is that each request for your static pages using the url will make an extra round-trip from the user's browser to your server (once for the 404 page, and then once to get the real page).
Also, you'd need to adjust my above code to avoid triggering a 404 loop in the case of an actual url being incorrect by adding a check something like:
var loopcheck = window.location.IndexOf(".html");
if (lookcheck != -1) {
window.location = "real404.html";
return;
}
Hope that helps.
You can just create index.html inside /static-pages/12345/ folder and it will be served.

External iFrame inside a pyramid project. No refresh when its updated

we include an iFrame inside a pyramid webpage.
The iFrame is a local html file which is not a pyramid webpage.
Everytime the HTML contents (=the iFrame) gets updated and I refresh or load the pyramid webpage with the iFrame again, the iFrame contents do not get updated. If I force a refresh with my browser then the iFrame has the new contents.
How to solve this issue?
Well, firstly, the question has no relation to Python or Pyramid whatsoever - Pyramid just generated you a blob of text which happened to be a HTML page. After that everything is happening in the browser - I suppose your "other page" has HTTP headers which say that the browser does not need to reload it each time and may cache it.
If you want to force reload of the "other" page each time the "pyramid page" is generated, you may try tricking the browser into thinking you want to load a new page each time. To do that, just add a bogus url parameter with some random number:
<iframe src="http://other.domain.com/somepage.html?blah=1452352235"></iframe>
where the number after blah= may be a timestamp or just a random number.

Categories