how to serve Angular2 app using Django builtin webserver?
I think I'm having some problems with the template and static paths from django.
My django project structure looks like following:
DjangoDir/
manage.py
project/
settings.py
urls.py
app1/
app2/
static/
app2/
something.js
something.css
templates/
app2/
index.html
urls.py
views.py
I have an angular2 app with following index:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Angular2</title>
<base href="/">
<link href="something.css" rel="stylesheet"/>
</head>
<body>
<app-root></app-root><script type="text/javascript" src="something.js"></script>
</body>
</html>
I get HTTP Status 404 (Not Found) code for the something.js and something.css file. Any ideas?
Here is my views.py in app2.
from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, 'app2/index.html')
UPDATE
Working solution, but still looking for alternatives.
Adding to all internal links in the angular2 app:
"/static/app2/"
<!--e.g.:-->
<script type="text/javascript" src="/static/app2/something.js"></script>
or
<!--{% load static %}-->
<script type="text/javascript" src="{% static 'app2/something.js' %}"></script>"
How to avoid changing every link in template and static files just to make angular2 app work with django?
I think that the better way to deal with Django and Angular 2+ is to build an API. You may create an RESTful API with Django REST Framework or Tastypie. Then your Angular2 app would consume that API to create the user-facing experience. You can check django-rest-angular2-example.
However, you want to manage static files, you can read Managing static files
Related
I have flask app with next structure:
templates/
dashboard.html
static/
css/
styles.css
js/
main.js
Dockerfile
app.py
In app.py I just have one endpoint to serve main page.
app.py:
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/home")
def dashboard():
return render_template('dashboard.html')
if __name__ == '__main__':
app.run(debug=True)
dashboard.html:
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>...</body>
<script type="text/javascript" src="{{url_for('static', filename='js/main.js')}}"></script>
</body>
</html>
The app is hosted on AWS ECR+Fargate ( I am not the person who did devops side).
The app works, but static files (js and css) are not loaded, error 404. What could I miss?
This is my index page in django
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/MaterialDesign-Webfont/3.8.95/css/materialdesignicons.css">
<meta charset="UTF-8">
<title>My test</title>
</head>
<body>
<div id="app">
<h1>TEST</h1>
</div>
{% render_bundle 'main' %}
</body>
</html>
And this is a standard Vue navbar.
<template>
<v-app id="sandbox">
<v-navigation-drawer
v-model="primaryDrawer.model"
:clipped="primaryDrawer.clipped"
:floating="primaryDrawer.floating"
:mini-variant="primaryDrawer.mini"
:permanent="primaryDrawer.type === 'permanent'"
:temporary="primaryDrawer.type === 'temporary'"
app
overflow
><v-switch
v-model="$vuetify.theme.dark"
primary
label="Dark"
></v-switch></v-navigation-drawer>
<v-app-bar
:clipped-left="primaryDrawer.clipped"
app
>
<v-app-bar-nav-icon
v-if="primaryDrawer.type !== 'permanent'"
#click.stop="primaryDrawer.model = !primaryDrawer.model"
></v-app-bar-nav-icon>
<v-toolbar-title>Vuetify</v-toolbar-title>
</v-app-bar>
</v-app>
</template>
The code is working, and i can see Vue being loaded when i open my Django site.
The problem with this is that i don't know how to get them along. For example, i added a <h1>TEST</h1> but it does not appear when i load Vue, since the Vue part covers it. I also don't understand, if i have a conditional on my Django template, such as {% if user.is_authenticated %} i can't use it on Vue, because it won't be loaded by it.
For example, i have a navbar. Instead of that navbar i want to use the below Vue navbar but i can't, because the current navbar has some links to parts of my site, and since the links are made in Django template language, they won't be loaded by Vue.
You should understand that Vue is a frontend framework that is agnostic to the backend, and Django is, in contrast a backend framework (that can be used in such way to be agnostic to the frontend, I assume this is what you are trying to do).
The way Vue works is that it renders the content inside the div#app tag in index.html, that's why your h1 tag doesn't work. you will have to include that h1 tag inside your vue app in the right component in order to work (don't forget to recompile your components after editing, in case you are using smthng like webpack...etc).
Regarding the Django conditionals part, the point is that now, your Vue app is a seperate application than the Django App (and they will have to communicate through an API using HTTP calls). So in order for authentication to work (or any other logic), you will have to handle that logic both in your Vue app and your Django app
It looks like a very basic question and I'm confused by the fact that I cannot find any sensible tutorial on that. I'm trying to setup Django + React production build. After running all kinds of transpilation, minification etc. I end up having .js and .css bundles, index.html and several other files like favicon, service-worker.js etc. Now I need to serve this with Django.
All of these files are static files and should probably be served as static files by the http server (nginx in my case). The variant I came up with was to modify index.html to make it a valid Django template: {% load static %} in the beginning, replace all hardcoded links with {% static 'filepath' %} and serve it using TemplateView, other files are served by nginx. This works fine, however, modifying build results looks like a bad idea. Generated bundles contain a unique hash for each build and I would need to replace that hash in the template after each build. I obviously can automate it but it looks weird. I would prefer not to touch build results at all, but how should I serve static files then? nginx is configured to serve static files under /static/ path and cannot serve files like service-worker.js as static files.
So the question is how do I configure Django + React for production so that I don't have to manually modify build results and can serve static files properly using nginx?
The main problem to combine React and Django is that Django wants to render the templates by itself, but React wants also to execute the render, since it has been created for that. That's why there a lot of approximations that use django just as as REST API when working with react.
But, if you want django to Render the templates to avoid having a Single Page Application (as react provides) and to use all the other tools from django, the main flow that we use in our company is:
You create your components, in js files. For example: component.js
You use babel to compile the JSX files to native Javascript, and babels creates, for example, component.build.js. Django will serve this compiled files, so react is going to be used only in develop tasks because all React code will be transformed to JS before moving to production. For django, all the react components will be just JS code already compiled.
You can use Webpack to automatically move component.build.js to a folder where django can serve them, for example your_project/static/your_app/component.buid.js
You create a django template base.html which will be used as the base template that all your templates will extend. Here you put the header and all your common scripts and styles. For example, bootstrap should be here if used. Remember to leave blocks in this base template to use them in the templates that are going to extend the base.html. Here is the base.html that we use:
{% with version="2.0" %}
<!DOCTYPE html>
{% load static %}
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="author" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- base styles goes here -->
<!-- include here bootstrap or styles that are common to all your website -->
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}"/>
<!-- custom styles for each app go into this block-->
{% block app_styles %}
<!-- here will go the apps local styles -->
{% endblock %}
</head>
<body>
{% block app %}
<!-- This block will be used by the apps to load their react components -->
{% endblock %}
<!-- base js go here -->
<script src="{% static 'common/pluggins/jquery3.4.1.min.js' %}"></script>
</script>
<script src="{% static 'common/pluggins/fontawesome.js' %}"></script>
<script src="{% static 'common/scripts/base.js' %}?v={{version}}"></script> <!-- File for common utils -->
<!-- custom js for each app go here. You should define your Content() here -->
{% block local_scripts %}
<!-- here will go the app local scripts -->
{% endblock %}
</body>
</html>
{% endwith %}
Create the templates for each of your django apps, by extending the base.html. Remember to include here the <div> that is going to be used by react to render the content. Aslo, remember that this is the place to include the component.build.js compiled JS file that bable created before. Here there is an example that we use to build a dashboard.html in our website:
{% extends 'common/base.html' %}
{% load static %}
{% block app_styles %}
<link rel="stylesheet" href="{% static 'dashboard/styles/dashboard.css' %}?v={{version}}">
{% endblock %}
{% block app %}
<!-- Here is the div used by react -->
<div id="myreact-content"></div>
{% endblock %}
{% block local_scripts %}
<!-- IMPORTANT: Import here the compiled file -->
<script src="{% static 'component.build.js' %}"></script>
{% endblock %}
Set the correct urls.py in your projects and in your app
Set the correct configuration in setting.py to make accesible the static js/css files and the templates
Run your django server and You're done!
In this video you have a small guide on how to configure npm, babel and django. With a correct configuration, everything will be updated automatically when you change some code in your JSX (not compiled) files, so the develop tasks will be more friendly.
https://www.youtube.com/watch?v=Mx3ChaYA0Gw
I have an angular 2 front-end with already written links between html js, css and other files such as images, that I would like to serve using Django.
The structure from Angular 2 looks like following:
-->index.html
-->test.js
-->test.css
HTML file:
<!doctype html>
<html lang="en">
<head>
<link href="test.css" rel="stylesheet"/>
</head>
<body>
<script type="text/javascript" src="test.js">
</body>
I wouldn't like to change the given paths from the angular 2 app, instead I would like to know the workaround to serve this files in django without using "/static/< appname>/" or "/static/" prefix or template tags in every link.
Update
Trying to avoid
<!doctype html>
<html lang="en">
<head>
<link href="/static/test.css" rel="stylesheet"/>
</head>
<body>
<script type="text/javascript" src="/static/test.js">
</body>
and avoiding this:
{% load static %} <link href="{% static "example.jpg" %}" rel="stylesheet"/>
In other words, trying to adapt django builtin webserver to serve angular files without adapting ("static" prefix or tag) them to django.
Thank you in advance!
You say you want to "serve your files" from Django, but I think you really want to serve them from something like Nginx. For example,
location = /js/test.js {
root /path/to/js/;
}
in your nginx file. For the purposes of Angular2 URLs, you can pretend that Django doesn't exist.
When I use the url(r'^consultar/$', 'rcb.core.views.consultar'), in browser http://localhost:8000/consultar the consultar.html file find the jquery-1.11.2.min.js file, appearing the following information:
Remote Address:127.0.0.1:8000
Request URL:http://localhost:8000/static/js/jquery-1.11.2.min.js
Request Method:GET
Status Code:200 OK
But when I use the url(r'^proposta/consultar/$', 'rcb.core.views.consultar'), in browser http://localhost:8000/proposta/consultar/ the consultar.html file not find the jquery-1.11.2.min file.js. Appearing the following error:
Remote Address:127.0.0.1:8000
Request URL:http://localhost:8000/proposta/static/js/jquery-1.11.2.min.js
Request Method:GET
Status Code:404 NOT FOUND
Could someone help me fix the code to run the url http://localhost:8000/proposta/consultar/
Below is the code and the structure of files and directories:
consultar.html
{% extends 'base.html' %}
....
base.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="../static/js/jquery-1.11.2.min.js" type="text/javascript"></script>
</head>
<body>
{% block corpo %}{% endblock %}
</body>
</html>
views.py
def consultar(request):
propostas_salvas=search()
return render_to_response('consultar.html', { 'propostas_salvas' : propostas_salvas}, context_instance=RequestContext(request))
My structure of files and directories is:
rcb (Project)
core (is the App)
static
js
jquery-1.11.2.min.js
template
base.html
consultar.html
views.py
...
...
...
You should use path to javascript relative to your domain, not to document you're requesting, because for each document relative path to javascript would be different. So change that line:
<script src="../static/js/jquery-1.11.2.min.js" type="text/javascript"></script>
into:
<script src="/static/js/jquery-1.11.2.min.js" type="text/javascript"></script>
Or even better, load static in your template and use static file management built into django:
<script src="{% static "js/jquery-1.11.2.min.js" %}" type="text/javascript"></script>
That way you can change later your STATIC_URL in settings and django will correct path to your static files. Even if they are on different domain (some CDN or no-cookie domain just for your static files).