I've integrated Reactjs with Django by having a function to access build/index.html. The below codes show how I do that.
config/urls.py
urlpatterns = [
...
re_path(r'search/', react_views.ReactAppView.as_view()),
]
PROJECT_NAME/views.py
class ReactAppView(View):
def get(self, request):
try:
with open(os.path.join(str(settings.BASE_DIR), 'frontend', 'build', 'index.html')) as file:
return HttpResponse(file.read())
except:
return HttpResponse(
"""
Build your React app.
""",
status=501,
)
ReactAppView function accesses index.html which is created with yarn build on React side. Basically, I used React just for search view, and other than search view, I used jQuery as it was developed with jQuery first.
Since I found that I need Next.js to use Server Side Rendering (SSR) with React, I've been trying to migrate React app to Next.js. But, Next.js doesn't have index.html. It just has pages/index.js instead.
I've tried very hard to figure out how to integrate Django with Next.js, but I can't find any helpful resource. Can anyone help me about this?
It seems like you want to serve static files (i.e. React or Next.js bundles).
Django has a guide on how to do this (via django.contrib.staticfiles)
The simplest example (straight from the docs) is:
set the STATIC_FILES folder:
STATIC_URL = '/static/'
Put the index.html file there and reference it as /static/index.html.
For more info on staticfiles, please refer to the official documentation: https://docs.djangoproject.com/en/4.0/howto/static-files/
On the Next.js side, you need to either follow the sample at https://nextjs.org/docs/advanced-features/static-html-export or create manually an index.html that includes all next.js bundles that you are using.
I know it's too late, but Ored's answer is not working with Nextjs.
When using a React SPA, all of the react code will run on the client's browser, and of course in that case all you need is just serve the React build artifacts as staticfiles.
But with Nextjs using SSR, you need to run the Nextjs server (using Nodejs) and you should integrate these 2 servers (Django and Nextjs) to work together.
So, if you are starting a new project you should just use Django as a web service and let Nextjs to be the interface of your application, but if you already have a Django application and want to use Nextjs, check out following article and GitHub repo:
Medium: Django + Next.js The Easy Way
Github: django-nextjs
Related
I just started a project with a frontend developer. We are trying to add social authentication (Discord), without success.
I want to use django as a REST API for the backend, I installed django-allauth which seems to work when I use a django template to connect using Discord:
{% load socialaccount %}
{% providers_media_js %}
<html>
<head>
<title>Discord Registration</title>
</head>
<body>
{{user}}
Discord Connect
</html>
But I have no idea how to share this connection with the frontend (made with vuejs). I've never worked on a project where backend and frontend are not in the same application... What to do on the frontend and what to do on the backend? And the main question, how? I've been working on it for two days and I'm still completely lost.
There are 2 ways you can make this work depending upon how you are planning to deploy to production.
Method 1:
Frontend developer can run npm run build command which will generate a folder called dist. You have to serve this folder from your django application. Do the following in your Django application:
In settings.py file, add VUE_FOLDER = 'PATH_TO_DIST_FOLDER/dist'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, VUE_FOLDER)],
}
In urls.py file, add path('', TemplateView.as_view(template_name='index.html'), name="home"
The above line will serve the Vue index.html file as django home page.
This way your production will have only one port which will serve only one application which has both UI and django app. All API which are present in urls.py file can be accessed by UI. No need to worry about CORS.
Method 2:
UI can be a separate app hosted in one port and your django application can be a separate app hosted in another port. In that case your django application should support CORS as all API calls from UI will be considered as cross origin calls. UI should include the complete url path http://django-server:port/api_name/ to access the API.
In both the case, you no need to use django template and UI can be an independent app. Routing will be taken care by vue-router. Django app will act as server and will handle only APIs. Hope this helps.
I'm trying to setup a project using Django for backend and React for frontend. The project has several screens, a lot of information in DB and images generated by the backend, and will include some authentication and user permissions for different screens.
According to what I found - the best way to do it is having Django render an html file:
def index(request):
return render(request, 'frontend/index.html')
which references a .js file:
<script src="{% static "frontend/main.js" %}"></script>
Which is created using Webpack.
This main.js retrieves the data it needs from Django using a REST api:
fetch("...some Django endpoint..").then(response => ... this.setState(...retrieved data...))
Unlike when just using Django for backend + Django templates for frontend where the backend can just send the context directly to the template:
def index(request):
context = {'information': .... retrieve info from DB}
return HttpResponse(loader.get_template('bla/index.html').render(context, request))
and the template can use this info directly, without referencing the backend again:
{% for bla in information %}
I'm wondering if it is a reasonable setup?
It seems excessive to have the frontend use REST for retrieving each piece of information it needs and the backend exposing another REST api for each part of data it needs to supply (Instead of just pushing all of the information to a single dict and sending it over along with the template),
Also, it requires at least 2 RTTs to render the full page (which I guess usually is okay)
According to what I found - the best way to do it is having Django render an html file:
I disagree with this line. I would say it would be best to keep the react app and Django app totally separate.
I believe, the Django application should solely provide APIs and adminsite(maybe, depending on your needs).
And the frontend should be a standalone app which can be served through NGINX/ExpressJs/Apache etc.
There are several advantages of this setup.
From Django application's perspective, the advantages are:
Django will not be burdened to serve the Frontend. Use gunicorn or uwsgi to serve the Django APIs.
As Django will provide data through API only, it will provide clarity on how the frontend application will communicate with the backend. I know that you can send data using context when Django serves the react app, but this might cause confusion because of API and context's co-existence.
You can use Token based authentication, JWT etc instead of Django's own session based authentication, which have a lot of other advantages.
Freeing your frontend application from backend is the best thing can happen for the frontend. Like for example:
if you had Django to serve the frontend, you were almost forced to use session based auth(its not like you can't use other auths, but whats the point of having multiple auth systems)
You couldn't have used server side rendering with Django rendering the frontend.
Lets say, you are have no idea about how Django works, but you will be forced to setup a Django application in your local machine, because it serves the frontend.
You couldn't have used ExpressJs to serve the frontend, or use the advantages of using NGINX to serve those contents.
Deployment would be complicated if you have docker setup. In this case, you would have had to use one Docker Container to serve everything, else you could have used multiple docker containers to serve backend/frontend.
Lets say, you want to serve the Django application in one server, frontend from other server, but with Django tightly coupled with Frontend, you can't do this setup.
You can easily connect external RESTful API services without bothering about Django. Even you can use any other frameworks like Tornado, Flask etc(but DRF+Django ORM is awesome) to develop APIs.
There are some more generic advantages of having backend and frontend separated.
There is a fantastic tutorial which you can read on medium about setting up separate Django + ReactJs app.
You can use GraphQL, it has several advantages over REST, f.e.:
only one endpoint for entire app;
ability to fetch data with relations between them;
easy data structure modifications on both sides;
advanced client with cache/normalization/subscriptions/optimistic updates (I prefer apollo to relay);
can be used as datasource for static site generation (SEO);
you can stich other services/APIs;
... many more.
Using react Server Side Rendering you can get pages without additional requests - 'prefilled'/rehydrated, ready for interactions - better Time to Interactive.
Tutorial/demo: django-graphql-apollo-react-demo
I want to build a project with Django framework, it includes website and mobile app, website is built based on Django template, and mobile app needs rest api. How can I do it with only one copy of source code?
In other words, can I create one project, in which there are several django apps, it supports returning both rendering template and json for mobile app?
I know we can use Angular JS in website, then both website and mobile app access rest api build with Django-Rest-Framework. But I have no idea about Angular JS and there is no time for me to learn it.
Please help.
This is easy to achieve if you leverage the power of HTTP headers, specifically speaking the "Content-Type" header
(HTTP 1.1 headers specification)
The way I personally use it is something like this:
def my_view_name(request):
if 'CONTENT_TYPE' in request.META and \
request.META['CONTENT_TYPE'] == 'application/json':
return HttpResponse(
json.dumps({"foo":"bar"}),
content_type='application/json'
)
else:
return render_to_response(
'sometemplate.html', context
)
The code above is django-specific.
It allows you to control what kind of response the server doles out, based out what the client passes in. It can detect that a JSON response is needed by checking the Content-Type header.
Just ensure your mobile app makes its HTTP requests with the Content-Typeheader set to application/json
Hope that's what you wanted.
You can do it in one project. Have the same Model, but have different views for website and REST-api.
You can build one Common Backend to serve your data.
And you can do this without having a Django-rest-Framework(without having to use angular).
You are just going call the url of the backend.
For eg.,. lets say backend code is running at 127.0.0.1/8000, and you need to get a user's details, you are just going to call url 127.0.0.1:8000/get_user_details/ from mobile app or any other front end.
And please make a habit of forming/arranging data written in a different function so that it is reusable by both the Mobile app and the website.(plz see below)
### For browser website written in DJANGO (served in template by django):
def user_details_page(request):
get_user_details(someid) #### returns json of user details
render in template
#### And for the mobile App you could use **get_user_details(someid)** just to get json data.
def get_user_details(someid):
###do watever
return json ## of user details
And you can also use Django Rest Framework(without having to use angular), it gives you a lot of stability.
Or you can setup a entire new backend in Django Framework to serve data for mobile App.
I have created a REST API in Django to pull data from my database. I have a front end application built with Angular that makes calls to that same API. The API has a few URL's, and I have one other URL to serve up index.html and handle the routing. Angular injects the "#/" into the URL. Ideally I would not have that, but when I use the HTML5 mode and location provider, Django picks up the URL and does not see the specified URL in its list and therefore throws an error.
I have seen some resources online, but they are not very clear to me.
Basically, what are accepted best practices with regard to creating angular applications with a Django backend.
I appreciate your help! Thank you in advance.
If you want to serve the index.html for every url and then do the routing in angular you can do somethings like this in your <project_folder>.urls.py
from <your_app> import views
urlpatterns = patterns('',
url(r'^.*$', views.index),
)
I have a django project which is making use of django-rest-framework to provide an api for an angular client.
The entire angular app is developed separately to the django project, and doesn't make use of any django templates or suchlike.
Eventually the angular app will be served as a static asset via nginx or something along those lines.
However, during development, I would like the django development server to serve the angular app.
The issue I have is that none of the static assets in index.html are prefixed with STATIC_URL or a similar static prefix which django can look for.
Attempting to serve all non-api routes as static files as such:
urlpatterns += static(r'', document_root=settings.ANGULAR_APP_ROOT)
gives an exception
Empty static prefix not permitted
I know that in nodejs express server you can use something like:
app.use(express.static(path.join(config.root, 'app')));
which works seamlessly. I guess it searches for any paths in the configured folder and if any match the requested url, serves them.
I do not want to force django specific code/prefixes into the angular app (ala STATIC_URL etc)
What I'm looking for is some middleware which will offer a fallback route for anything unmatched by the existing urlpatterns and search a filesystem path for a matching asset and serve it if found.
Is it possible to get the static assets served like this with the django development server?