I want to serve a react project with Flask.
I need the index HTML to be served as a flask template so I can pass in a variable from Flask,
and the other static files (css, js, favicons) as normal static files.
How can I achieve that?
Edit: I just had the html sent as a flask template and put the static files into a folder which I declared as the static dir in flask.
As far as I know, you can not do that. Flask uses template htmls that are rendered on the server. Now if you ask whether can you code a react renderer for server-side rendering with Python/flask?, might be possible, I guess. But people built big companies around this idea, for example Vercel. So better team up. What you can do though you can make flask and react communicate through different ports. i.e. code your Flask back-end as a rest-api and build the react front-end.
Related
I'm self-learning web development, and I was confused about how blueprint and templates were different.
Blueprints support "common patterns within an application or across applications" - http://flask.pocoo.org/docs/1.0/blueprints/ but I don't see why templates can't suffice
Also, are these standard web terminology or just Flask specific?
Blueprint:
A Blueprint object works similarly to a Flask application object, but it is not actually an application. Rather it is a blueprint of how to construct or extend an application. It is particularly used for scaling large projects.
Blueprints are sets of applications in a application.
Blueprints may render templates to display the requested data.
Template:
Templates are used for rendering HTML document which are used to display in users browser. Templates file can be either static content or placeholder for dynamic data.
Templates are rendered by blueprint or an app which they pass data to templates.
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
I want to move my website to django which has a lot of images and css files linked to it. Also it uses Application cache for caching the static files.Since I have other apps working on the django I want to move this static one also to the django.So is it possible to run a webpage without rendering the static files dynamically and use the page as static webpage only(static files path relative to html not using django's static folder)? How to do this?
Assuming the HTML is also static, you should just move everything (HTML and relative files) to a static folder (no need to separate the HTML template since it is static as well), and then you can map it to any URL you want using your web server, e.g. you can put them inside {{ STATIC_ROOT }}/my-page/, and map example.com/my-page/ to that folder on the filesystem
Run collectstatic, Django will copy/generate the static files into your STATIC_ROOT folder on the filesystem https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#collectstatic
Then use a web server like Apache or Nginx to serve your /my-page URL directly without hitting your Django app. (set in Django with STATIC_URL), while the other requests are forwarded to your Django app
So e.g. your Django app will run on 127.0.0.1:8000, while nginx runs on the default HTTP/HTTPS port, and uses e.g. proxy_pass to talk to your Django app for the dynamic content
http://wiki.nginx.org/HttpProxyModule
I have a router
#app.route('/images/<filename>')
def images(filename):
send from(os.path.join('uploads', filename))
My images are saved in some directory called 'uploads'. And I configure nginx to serve static files.
My question is when I use url_for('images', filename='1.jpg') in jinja template, which should generate something like src="/images/1.jpg" in browser, if the user click this link, will nginx serve the file or flask serve it?
Another example:
when using url_for('static', filename='style.css') in template, is nginx serving it?
The solution shall work well, if follows these rules:
you know exactly what static files you are going to be served
your jinja based templates are generating proper links to these files
ngingx is properly configured to serve these static files
Under these (production) conditions, your Python code shall not get requests to these static files as they are served by nginx.
This is desired behaviour, as it off-loads python application by nginx, which can serve those files much more efficiently.
I'm writing a Google app engine app and obviously the default web app framework is a subset of Django. As such I'm using it's templating engine.
My question is if I have say the following code:
template_values = {
'first':first,
'second':second,
}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
And I want to reference the template value first in an externally included javascript file from index.html, do I just continue with the {{ first }} usage I'd go with in index.html itself or do I need to tell the framework about example.js somehow too so that it knows to replace the reference there?
Inserting the value into the javascript is probably a bad idea; wouldn't it make more sense for the script to be static and to have it grab the data either out of the DOM (assuming it's part of the HTML page you're rendering) or get the necessary data from the server using an AJAX call?
Disclaimer: my knowledge of app engine is limited so this answer may not serve your purpose.
In Django if you need to be able to pass variables from a view to a JS file you will have to ensure that the file is parsed by the template engine. In other words the file has to be served by Django. This means for e.g. that if you have a JS file in a media directory that is served by say, Nginx, you will not be able to use template variables in it.
I would expect the same to apply for app engine. But then see the disclaimer. I might be totally wrong :P