Cache busting with Django - python

I'm working on a website built with Django.
When I'm doing updates on the static files, the users have to hard refresh the website to get the latest version.
I'm using a CDN server to deliver my static files so using the built-in static storage from Django.
I don't know about the best practices but my idea is to generate a random string when I redeploy the website and have something like style.css?my_random_string.
I don't know how to handle such a global variable through the project (Using Gunicorn in production).
I have a RedisDB running, I can store the random string in it and clear it on redeployment.
I was thinking to have this variable globally available in templates with a context_processors.
What are your thoughts on this ?

Django's built-in contrib.staticfiles app already does this for you; see ManifestStaticFilesStorage and CachedStaticFilesStorage.

Here's my work around :
On deployment (from a bash script), I get the shasum of my css style.
I put this variable inside the environment.
I have a context processor for the template engine that will read from the environment.

Related

How to display user inputted blogs in flask production server

I'm using gunicorn and nginx to serve a flask application, my website has a blogging feature where users can write blogs, once they do, their input is saved as an html file (I use tinyMCE to generate it) and a flask view is added to a views.py file. Now, in deployment, I just used
use_reloader=True
This ensured that every time a new file was added, it was detected, now in production, I don't know how to implement it, gunicorn has --reload option but the docs say that it's only for development. Can someone please provide an insight on how to implement this feature? Thanks!
You don't need a new view for every html file. You could use a generic view that renders the appropriate html according to the url requested.

Django & React with django-webpack-loader vs Decoupled App structure linked to Rest API?

I am reading through the following tutorial:
http://v1k45.com/blog/modern-django-part-1-setting-up-django-and-react/
I can't quite grasp what the added value is of using something like django-webpack-loader to fully integrate react.js and django when you can completely decouple django from react, running a separate frontend which links to a DRF rest api.
I may be comparing apples to oranges here, but I am not sure. Any help ?
From the django-webpack-loader tutorial:
Now that we’ve handed off the build process webpack, only thing we need on the django side is to know which bundle to include in our html pages. This is where django-webpack-loader comes in. It’ll also raise exceptions when webpack fails to build a bundle and will show some useful information to help debug the problem. During development, webpack loader will also block requests while a new bundle is being generated so that only the latest bundles are loaded.
This is the core functionality of that loader. It tells django which are the current bundles to be served. It does not server side render your react app nor does it replace an API that the app needs to consume.
When developing a react app you usually use some kind of bundler that transpiles your javascript code to es5, uglyfies and minifies it. So every time your code changes a new bundle will be created containing your new javascript. A lot of people are using webpack for this task.
Now when a request arrives in django it needs to serve the basic html along with the css and js to be loaded by the client that contains the react app. So django needs to know the path to the files to link. But the path may constantly change when webpack rebuilds them. django-webpack-loader helps you to keep track of these changes and includes the correct paths to the current bundles for your react app to be fetched.
It is not a replacement for an API. Its sole task is to resolve the correct paths to your react app files.
EDIT
So the primary purpose of django-webpack-loader is to ensure that the paths to the most recent build are resolved correctly and in turn can be served. What is the reason these paths will change ?
Weppack appends a random hash to a new bundle like bundle.4j2a032fg.js. This way django can tell the client to cache the script so that it does not have to be re-request it every time. The client will only request a new bundle if the url/path changed. But this also requires that django knows the newest bundle with the correct hash.
does server side rendering occur with the use of Django templates ?
Server Side Rendering (SSR) in the context of react means that a nodejs server actually runs the react application once on the server to produce the initial markup of the app. This can then be statically served with the app. It reduces the perceived loading time for the user because the initial state of the app will immediately be shown and it allows for search engines to statically analyse the page which is good for SEO.
While django does render templates it is only the static html around the react app which it will render by default. Django does not render the react app itself. The react app still needs to initially render itself on the client. So to enable django do do true server side rendering you would have to run a nodejs process next to django that does the static rendering of the react app for django to serve.
In the tutorial they are using templates. Templates are loaded in the backend. So user gets fully rendered page.
With django rest framework you need to write seperate fronend. More about this: https://nickjanetakis.com/blog/server-side-templates-vs-rest-api-and-javascript-front-end

How to integrate angular 4 with Django

I'm trying to integrate Django and Angular 4 in the same app (running as two servers as well).
Well, reading the setup guide I noticed about the references to the node_modules directory (and some "hardcode" references).
Well, I wanna know if is possible to merge those technologies, I mean, to use the Django context and the http.get of angular to bind the results.
Or, those npm_modules should are included in my static directory?
But, where I should generate the angular project?
I know this is an old thread, but I finally got this to work the way I want/need. I have a Django backend with DRF and I wanted to use Angular 4 for the front end. My app depends on user logins and running two debug servers (one for Django and one for Angular) was not an option for me.
The secret sauce is to run this command:
ng build --watch true --output-path <your_static_scripts_dir>
I created my Angular app (using ng new app-name) inside my Django project, copied the index.html into the templates directory (and modified it to use my staticfiles directory).
Now I can edit my files in PyCharm, the watch will recompile the .ts files and I only have to run the built-in Django debug server.
What you can do is use angular in front-end with nodejs or a parent make an api with Django using DRF or tastypie ... but if you absolutely want to combine the two would have to consider the versions prior to the 2+ I even develop in Django but as we want to be present on the mobile platforms and native also then to the fact of API's or sometimes we pass the weapon to the left using only javascript. But do not forget in the world of technology what really matters is adaptation and agility

Inject constant (e.g., API-keys) when serving javascript files with Flask

I have a web application using Flask and Jinja2. I would like to inject different API-keys depending on if I'm serving the site in production or testing.
I could inject them using the Jinja templating engine and use inline <script>-tags to then access them from my other JS. But preferably I would like to have some kind of really simple template-string in my .js-files, like this:
_ready: Keen.ready(function() {
var client = new Keen({
projectId: $KEEN_PROJECT_ID$,
writeKey: $KEEN_WRITE_KEY$
});
and then replace those keywords when Flask serve the file. Of course changing the value of the constant depending on which environment the server is running.
Are there any good ways of doing this?
A good way to do this is by adding a global to jinja. See this answer
You can then inject the api key wherever you need and keep your template code clean by having the lookup logic somewhere else

Why should JavaScript files be localised differently in Django?

When localising Django application the makemessages command simply parses all the TXT, HTML and PY files and generates PO files for them but when localising JS files, you need to run the djangojs command. I haven't delved into the Django source to figure out why this done differently. Could someone explain?
I've read that in production environments, Apache is used to serve the application files while a simple proxy like Nginx is used to serve static files as this greatly reduces the load on the application server. With this scenario, I guess it works like this: when rendering a template, Django checks the requested locale, loads the appropriate localisation file and serves the template but JS on the other hand being served as static media doesn't get parsed by Django. Is this it?
(Its my first foray in to the world of localisation with Django and I'm packed full of question, many of who's answers I can't seem to find and therefore this post.)
Thanks
The reason why it's handled differently is in the docs.
Adding translations to JavaScript poses some problems:
JavaScript code doesn't have access to a gettext implementation.
JavaScript code doesn't have access to .po or .mo files; they need to be delivered by the server.
The translation catalogs for JavaScript should be kept as small as possible.
So essentially, the internal Python translation is done on the server. But for JS, there's another file served by the server, which contains all the required translations for user's language. And the translation is done on the user's side. So as you can see, it's a completely different strategy. Django helps by adding similar interface for JS files, even though they're handled in a completely different way.
I guess it works like this: when rendering a template, Django checks
the requested locale, loads the appropriate localisation file and
serves the template but JS on the other hand being served as static
media doesn't get parsed by Django. Is this it?
You are right in the first part, about handling templates. Handling JS works as I've explained above.
Note that Django JS translation mechanism, doesn't treat JS translations as static files. It uses a Django view to generate the JS file everytime (javascript_catalog mentioned in the docs linked in the first line).
That is one of the problems I've encountered. Such files don't need to be generated on every request. There are some projects that actually let you pack those JS translations as static files and enable you to cache them properly (like django-mediagenerator).

Categories