Django is a high-level Python framework that facilitates rapid development and offers a clear and pragmatic design. Django gains preference due to its robustness, scalability, and high-level abstraction of building dynamic websites in a Pythonic way.
Django is designed on the DRY (Don’t Repeat Yourself) principle and allows for automation on every repetitive step through the development lifecycle. This is where Django Template Language (DTL) comes into play. DTL allows for integrating Python logic into static HTML files to render them dynamically with server-side data.
Meanwhile, React is a versatile JavaScript library for building enhanced UIs. React is primarily used to develop single-page applications where data changes over time. It leverages a component-based architecture and uses declarative programming to construct user interfaces, which abstracts away the complexities of JavaScript. When compiled by the node package manager (npm), the code is compiled in plain JavaScript to run on any browser.
In this article, we will create a dynamic demo blog site using Django and React to showcase the fusion of Django’s server-side functionalities and React’s interactive user interface.
Django is primarily designed to serve static files, and React’s component-based framework can easily mount on Django-governed templates. This gives us the advantage of making the static, single-page application framework of React act like a dynamic multi-page application.
React is designed to work in isolation, rendering its components in the client browser and updating the entire application whenever drastic changes are required. But with Django serving its static files, the entire application can reside in one unit. This not only seamlessly integrates the server-side backend with the client’s browser, but also lets frontend and backend developers work on scaling or debugging the entire application without stepping on each other’s toes.
In this article, we are going to experiment with the model of a blog site whose frontend is rendered in React. This will demonstrate how Django can leverage the flexibility of a versatile frontend framework like React to integrate a robust backend framework into one unit.
The website will simply display choices of blog post categories for users to pick, as well as the article ID and category on the client’s browser. Such a Django-React setup is ideal for not only dynamically rendering multiple React components but also updating them with server-side data without redeploying the entire framework every time.
This is a demo of the basic website we’ll build:
We will start by initializing a Django template, index.html
, located in the templates directory of our blogSelector
app. This will include the div tags that our React app will mount on our index.html
, which looks something like this:
{% load static %} <!DOCTYPE html> <html> <head> <title>Article Categories</title> </head> <body> <div id="content" data-article-id="48" data-category="home_decor"></div> <div id="category-choice" data-categories='["Home Decor", "Sports", "Health", "Tech", "Science"]'></div> <script src="{% static 'js/main.93d099db.js' %}"></script> </body> </html>
Notice that each div has a unique ID that corresponds to a specific React component. This way, upon rendering this HTML template on the Django server side, the corresponding React components will latch on to these divs.
Rendering React components via HTML template isn’t a big deal in itself — but things become interesting when DTL comes into play. In the script tag, we linked React’s main.js
. By defining it in a Django template ({% %}
), we have linked our index.html
directly to the static files in our React app’s build directory.
This way, the DOM structure that React will load its components into can be manipulated by Django to make the otherwise static React components render dynamically.
With the Django template ready to serve React, we can define two React components for each div. Because we want to display the article ID and the category sent from the server to the client browser, we can define a JavaScript file in our blogSelector React app’s directory to do that. So our Article.js
script will simply acquire the article ID and category props and render them in a div.
Next, we need to define another JavaScript file in the same directory to handle the available categories list sent from the Django template. For that, we can make a blog_selection.js
that will take an argument as a list of categories and render it in a div.
With our article and catagory_selection
components ready, we can now define our index.js
, which is the entry point of our React app. The code will be as follows:
import React from 'react'; import ReactDOM from 'react-dom/client'; import Article from './Article'; import Catagory_selection from './catagory_selection'; document.addEventListener('DOMContentLoaded', () => { const articleContainer = document.getElementById('content'); if (articleContainer) { const articleId = articleContainer.getAttribute('data-article-id'); const category = articleContainer.getAttribute('data-category'); const root = ReactDOM.createRoot(articleContainer); root.render(<Article article_id={articleId} category={category} />); } const categoryContainer = document.getElementById('category-choice'); if (categoryContainer) { const categoriesString = categoryContainer.getAttribute('data-categories'); const categories = JSON.parse(categoriesString); const root = ReactDOM.createRoot(categoryContainer); root.render(<Catagory_selection catagory_selector={categories} />); } });
The structure of index.js
is designed to become the entry point for Django to our blogSelector
app. When the client’s server makes a request, index.html
on the server side gets called, loading the DOM. This triggers our event listener in index.js
, and the 'content'
and 'category-choice'
divs elements are acquired by React via their ID names.
Then, the article ID, category, and choice attributes are acquired from their respective divs. Finally, the article and category_selection
components are mounted on the DOM via the root.render
function.
You can see, from a data flow perspective, that the Django template is completely in control of what the React app renders on the client’s browser.
When passing data from Django to the React components to be rendered, we’ll use the view.py
file in our Django app’s directory. For example, we can send properties such as article ID, category, and available categories as arguments to index.html
, directly where it is rendered.
The code for our views.py
will be something like this:
from django.shortcuts import render # Create your views here. def index(request): context = { 'article_id': '49', # Example article ID 'catagory': 'sports', # Example category # Dynamically generate categories list as JSON string if needed 'catagories': '["house Decor", "Sports", "Health", "Tech", "Science"]' } return render(request, "blogSelector/index.html", context)
To catch these props, we can update our index.html
code to include the DTL placeholders like this:
{% load static %} <!DOCTYPE html> <html> <head> <title>Article Categories</title> </head> <body> <div id="content" data-article-id="{{ article_id }}" data-catagory="{{ catagory }}"></div> <div id="catagory-choice" data-catagories='{{ catagories }}'></div> <script src="{% static 'js/main.95696f76.js' %}"></script> </body> </html>
By making these simple changes on the server side, we can now make our React app, functioning as an SPA (single-page application), act as a multi-page application.
In the current setup so far, our blogs are dynamically being rendered to the site from the Django servers. This server is the gateway for all kinds of personalizations on the site.
The most basic setup we might want to include could be simply to incorporate state management in the site such that when the user selects a category, it is sent to the server side via API to fetch the corresponding article ID and display it on the client’s browser.
This can be done in several ways on the React side but DTL gives you enhanced flexibility with how to handle user requests on the fly, which is quite hard to cater to with the limitations of static page rendering in React.
We can enhance our views.py
file to handle the POST
request triggered by a specific state change, by implementing these necessary modifications:
CATEGORY_TO_ARTICLE_ID = { 'Home Decor': '101', 'Sports': '102', 'Health': '103', 'Tech': '104', 'Science': '105', } @csrf_exempt def get_article_id(request): if request.method == 'POST': data = json.loads(request.body) category = data.get('category') article_id = determine_article_id_based_on_category(category) return JsonResponse({'articleId': article_id})
We just simply defined a dictionary that maps article IDs to their categories and whichever category is selected by the user is then used to fetch its corresponding article ID and send it back to the client.
Of course, this is just a demonstration but it gives insights into what Django views
paired with DTL can achieve in the context of dynamic page rendering by handling complex scenarios seamlessly between the frontend and backend.
In real implementations, the mapping technique could be used to fetch entire relevant articles from databases or Fetch APIs and add constraints according to the user’s profile to get personalized content.
React component codes should be in separate JavaScript files or a dedicated React app. You can easily build a React app using npm CLI commands. This distinction makes the React codebase modular and maintainable and allows frontend developers to work within their comfort zone without interfering with Django’s templates.
Build the finalized React app by running npm run build
to compile the React app into static files. Django can then serve these static files with its templates, which are rendered upon user request, and React components defined in the main.js
of the static files can mount on them easily.
The integration of these two powerful frameworks can give rise to complexity and frustration if errors are not handled well. Some debugging techniques can save you a lot of headaches.
You need to make sure that Django is correctly configured to serve the static files that hold your React application. You can do this by ensuring that STATIC_URL
and STATICFILES_DIRS
in your settings.py
are pointing to the right directories. Incorrect configuration can lead to React’s built files not being found or served correctly.
When you build the React app, the output is located in the build directory of your React project’s root directory and this needs to be accessible to Django. You can copy the js
folder from build/static
to the static folder found in your Django app’s root directory or link it in the settings.py
for a more robust link.
Remember that upon build, React adds a cache reference to the name main.js
file so you can use Django’s collect static command to ensure that the latest version of your React app is served by Django.
Leveraging browser developer tools to inspect network requests for static files can give you insights into what HTML content is being rendered as compared to what you expect. Checking for 404 errors, which manifest if the static files of your React build directory are not properly linked to Django, can let you pinpoint the missing fields that are causing errors. Other than that, the browser extension React Developer Tools can be valuable for inspecting the React component hierarchy and state.
When passing data from Django to React via data attributes, you need to ensure that the data is correctly serialized and deserialized as expected by methods like JSON.parse()
. If you don’t ensure this, you could face improper JSON formatting or HTML escaping that can break the data flow.
Placing console.log
statements strategically in your React code can help you avoid prolonged debugging sessions. Keeping an eye on Django’s logging framework to diagnose backend issues can be immensely helpful in determining if the source of the bug is on the frontend or backend and telling you exactly where the integration is failing.
In the guide, we covered key steps involved in integrating a React application with Django through the practical example of a blogsite web application. We discussed how such an integration can let us have the best of both of these powerful frameworks.
We also demonstrated how Django templating language (DTL) plays a pivotal role in dynamically rendering HTML with server-side data and blending Django’s backend capabilities with React’s responsive frontend components. We saw code samples for React frontend and Django backend files to reap the SPA benefits of React with Django’s backend functionalities, creating dynamic webpages that are scalable and interactive.
The article also sheds light on debugging tips and best practices to make the development process less tedious and highly flexible, allowing multiple teams to contribute to the workflows without interfering with each other. Django and React can be a great choice in the diverse landscape of web development. For another example of integrating Django and React in a project, check out this tutorial for using the Django REST framework and React.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how to implement one-way and two-way data binding in Vue.js, using v-model and advanced techniques like defineModel for better apps.
Compare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.