I have used Django a lot over the years. I’d say I used it since inception but I missed the first few months of its announcement which had core changes and the framework went through a lot at that time. However I have noticed its growth and have lived it day and night as I was using it on a daily basis as a developer and systems architect. My love for the framework has made me realize below that it’s not going anywhere and will not be obsolete anytime soon. But don’t take my word for it lets go through a deep dive and analyze a lot of different areas of where it does well and where it doesn’t.
Summary
Below I will attempt to give you a quick overview of which categories I think Django is declining and which it’s doing great at. After that based on your use-case and requirements you an decide if Django is going to be part of your next future project. The truth is that the Django has been a stable project that has consistently grown over the years and trusted by a lot of great vendors out there. Having said that below you will see a few areas where it can improve and do a bit better on.
Django | |
---|---|
Security | Very good |
Maintainability | Good |
Scalability | Good |
Cloud | Poor |
Innovation | Poor |
Community | Very good |
Third Party | Good |
Versatility | Very good |
Documentation | Very good |
Learning Difficulty | Very good |
The reason I did this extensive summary list on the table above is to demonstrate to you that Django is not becoming obsolete anytime soon. If you are worried about keeping your job please consider all the cases above where it ticks all the checkmarks!
Is Django Declining
The short answer is no, Django is not declining yet however it does have some factors that are weighing against it. Below I’m going to give you a list of why I think Django is still alive and kicking in 2023. Keep in mind the framework has seen massive growth since inception and has been adopted by a lot of major vendors.
Django remains a strong and popular choice for web development due to its active community, large ecosystem of third-party packages, high level of abstraction, strong security features, excellent documentation, versatility, and compatibility with modern web development tools. Below I’m going to give you my take and explain of why I do not think Django is on a decline.
Active and Engaged Community
Django has a very active and engaged community of developers, which means the framework is constantly being improved and updated. This ensures that the framework stays up-to-date with the latest developments in web development and is always evolving to meet the needs of modern web applications.
If you quickly take a look at how simple they’ve made it to report a bug you will realize that this is a framework that welcomes the community feedback. They basically ask in my opinion of the bare minimum you can from a developer.
# Find a bug in the Django framework # Submit a bug report to the Django community # Step 1: Reproduce the bug # Step 2: Create a new issue on the Django issue tracker # Step 3: Provide a clear description of the bug and how to reproduce it # Step 4: Wait for a response from the Django community # Step 5: Work with the Django community to resolve the issue
Large Ecosystem of Third-Party Packages
Django has a large ecosystem of third-party packages and libraries, which greatly expands the functionality of the framework and makes it possible to build complex and sophisticated web applications quickly and easily.
Below you’d see how easy you can use an external app such as django-crispy-forms package to create a form with a bootstrap layout.
# Install the django-crispy-forms package pip install django-crispy-forms # Add 'crispy_forms' to your INSTALLED_APPS in settings.py INSTALLED_APPS = [ ... 'crispy_forms', ... ] # Use the crispy tag in your template to render the form with a bootstrap layout {% load crispy_forms_tags %} <form method="post"> {% csrf_token %} {{ form|crispy }} <button type="submit">Submit</button> </form>
High-Level of Abstraction
Django is a high-level framework that provides a lot of built-in functionality and abstractions. This makes it easy for developers to create complex web applications without having to worry about low-level implementation details.
Let’s take look at a built-in form that Django offers. ModelForms is used to create a form that automatically maps to a model.
# Create a model for a blog post from django.db import models class Post(models.Model): title = models.CharField(max_length=200) body = models.TextField() published_date = models.DateTimeField(auto_now_add=True) # Create a ModelForm for the Post model from django import forms class PostForm(forms.ModelForm): class Meta: model = Post fields = ['title', 'body'] # Use the PostForm in a view to create a new blog post from django.shortcuts import render, redirect def create_post(request): if request.method == 'POST': form = PostForm(request.POST) if form.is_valid(): post = form.save() return redirect('post_detail', pk=post.pk) else: form = PostForm() return render(request, 'create_post.html', {'form': form})
Strong Security Features
Django has a number of built-in security features that help protect web applications against common attacks.
Cross-site scripting (XSS) protection
Django provides built-in protection against cross-site scripting attacks, which are a common type of attack where an attacker injects malicious code into a web page viewed by other users. Django does this by automatically escaping any data that is displayed in a template.
Let’s say we have a simple Django view that renders a template:
from django.shortcuts import render def my_view(request): context = { 'user_input': request.GET.get('user_input', ''), } return render(request, 'my_template.html', context)
In this example, the view takes user input from the query string and passes it to the template context as user_input
. If the user input contains script tags or other HTML markup, this could be used for an XSS attack.
To protect against this, Django provides a built-in template tag called escape
that can be used to escape any user input that will be displayed in the template:
{% extends 'base.html' %} {% block content %} <h1>User Input: {{ user_input|escape }}</h1> {% endblock %}
In this example, we use the escape
template filter to escape the user input before it is displayed in the HTML. This means that any HTML markup in the user input will be displayed as plain text, preventing any XSS attacks.
Additionally, Django provides a middleware called django.middleware.security.SecurityMiddleware
that can be used to add various security headers to HTTP responses, including the X-XSS-Protection
header, which helps protect against XSS attacks in some browsers.
Overall, Django provides several tools to help protect against XSS attacks, including input validation, HTML escaping, and security headers.
Cross-site request forgery (CSRF) protection
Django provides built-in protection against CSRF attacks, which are a type of attack where an attacker tricks a user into performing an action on a website without their knowledge or consent. Django does this by generating a unique token for each user session, which is included in any form submissions. This token is then validated by Django on the server side to ensure that the request is legitimate.
Django’s CSRF protection in a template:
<form action="/submit-form/" method="POST"> {% csrf_token %} <input type="text" name="username"> <input type="password" name="password"> <input type="submit" value="Submit"> </form>
The {% csrf_token %}
template tag will insert a hidden input field containing the unique token for the user’s session. This token will be validated by Django when the form is submitted to ensure that the request is legitimate.
Password hashing
Django uses strong, one-way password hashing algorithms to store user passwords securely. This means that even if an attacker gains access to the database, they won’t be able to read the passwords in plain text.
Django’s password hashing functionality:
from django.contrib.auth.hashers import make_password, check_password # Hash a password hashed_password = make_password('password123') # Check a password password_matches = check_password('password123', hashed_password)
The make_password
function will hash the password using Django’s default password hashing algorithm. The check_password
function can be used to check if a password matches a given hashed password.
Overall, Django’s built-in security features make it a strong choice for developing secure web applications.
Tied with the above Django provides a built-in user authentication system that makes it easy to add user accounts to a web application. It also includes an authorization system that allows you to define permissions for different types of users.
SQL injection protection
Django provides protection against SQL injection attacks, which are a type of attack where an attacker injects malicious SQL code into a web application’s database. Django does this by automatically sanitizing any user input that is used in a database query.
Consider a view function in Django that retrieves all blog posts from a database:
from django.shortcuts import render from myapp.models import BlogPost def get_all_blog_posts(request): blog_posts = BlogPost.objects.all() return render(request, 'blog_posts.html', {'blog_posts': blog_posts})
This view function retrieves all blog posts from the BlogPost
model using Django’s built-in Object-Relational Mapping (ORM) system. Django’s ORM system translates Python code into SQL queries, and it automatically escapes any user-provided data to prevent SQL injection attacks.
For example, let’s say we have a model for blog posts with the following fields:
from django.db import models class BlogPost(models.Model): title = models.CharField(max_length=200) content = models.TextField() pub_date = models.DateTimeField(auto_now_add=True)
Now let’s say a user submits a search query to find all blog posts that contain the word “django”. We can modify our view function to filter the blog posts based on the user’s search query:
def search_blog_posts(request): query = request.GET.get('q') blog_posts = BlogPost.objects.filter(content__contains=query) return render(request, 'blog_posts.html', {'blog_posts': blog_posts})
In this case, Django automatically escapes the query
parameter to prevent SQL injection. If a user tries to submit a malicious query that includes SQL code, Django will automatically escape that code to prevent it from being executed by the database.
So, in summary, Django’s built-in ORM system automatically escapes user-provided data to prevent SQL injection attacks.
Excellent Documentation
Django has always been known for its comprehensive and detailed documentation, which is a significant advantage over many other web frameworks. The documentation covers everything from getting started with Django to more advanced topics, making it easy for developers of all levels to understand and use the framework effectively.
One of the best ways to showcase the strength of Django’s documentation is to look at some examples of it in action. Here’s an example of how Django’s documentation makes it easy to get started with creating a new project.
Maintainability
Django is known for its clean and maintainable code, thanks to its use of the Model-View-Template (MVT) architecture. Here’s an example of how you can use Django’s MVT architecture to build a simple blog:
# models.py from django.db import models class Post(models.Model): title = models.CharField(max_length=255) content = models.TextField() pub_date = models.DateTimeField(auto_now_add=True) # views.py from django.shortcuts import render from .models import Post def post_list(request): posts = Post.objects.all() return render(request, 'blog/post_list.html', {'posts': posts}) # templates/blog/post_list.html {% for post in posts %} <div class="post"> <h2>{{ post.title }}</h2> <p>{{ post.content }}</p> <p>{{ post.pub_date }}</p> </div> {% endfor %}
This code defines a Post
model and a post_list
view that retrieves all posts from the database and renders them using a simple HTML template. With this code, you can easily create a maintainable and scalable blog in Django.
Versatility
Django is a versatile framework that can be used to build a wide range of web applications. A quick sample of a short version of an e-commerce like site is shown below:
# models.py from django.db import models from django.contrib.auth.models import User class Product(models.Model): name = models.CharField(max_length=255) price = models.DecimalField(max_digits=10, decimal_places=2) description = models.TextField() class Order(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) products = models.ManyToManyField(Product) total_price = models.DecimalField(max_digits=10, decimal_places=2)
This code defines two models: Product
and Order
. Product
represents a product in the e-commerce store, while Order
represents an order placed by a user. With these models, you can easily create a simple e-commerce site that allows users to browse products, add them to their cart, and place orders.
Scalability
While it’s true that Django may not be as scalable as some other web frameworks, it’s still quite capable of handling high traffic and large datasets. Using celery you can setup tasks in Django which allows you to scale your background jobs without having to worry about managing them and writing all the boiler plate you’d usually do. The below example is a simple case of sending an email as a background task.
# tasks.py from celery import Celery from django.core.mail import send_mail app = Celery('tasks', broker='amqp://guest@localhost//') @app.task def send_email(subject, message, from_email, recipient_list): send_mail(subject, message, from_email, recipient_list)
With this code, you can easily offload time-consuming tasks like sending emails to a separate worker process, leaving the web server free to handle incoming requests. This can significantly improve the performance and scalability of your Django application.
Where Django Is Falling Behind
In the sections below I want to cover some areas of where Django is falling behind. The truth is that we are nit picking here but I do want to make those aware for you to be aligned before you invest in a project with Django.
Compatibility with Modern Web Development Tools
I know I went through a huge list of many areas of why Django is not becoming obsolete anytime soon but there are some concerns and criticisms about Python Django that may cause some developers and businesses to question its relevance and effectiveness.
One reason why some people may view Python Django as becoming obsolete is the rise of newer, more lightweight web development frameworks that offer similar functionality and features, but with less overhead and complexity. These newer frameworks, such as Flask, FastAPI, and Tornado, are often touted as more flexible, scalable, and easier to use than Django, which may make them more attractive options for developers and businesses.
Going on with the list Django is that it can be slow and resource-intensive, which can be a significant problem for applications that require high performance and low latency. Additionally, Django’s reliance on traditional web development paradigms, such as the Model-View-Controller (MVC) architecture, may make it less suitable for modern, real-time applications that require more complex data flows and interactivity.
Some developers and businesses may view Python Django as becoming obsolete due to its perceived lack of innovation and progress in recent years. While Django has undergone significant updates and improvements over the years, some critics argue that it has failed to keep up with the fast-changing needs and trends in web development, such as microservices, serverless architectures, and single-page applications.
Slow Innovation
Yes this you heard right, the perceived lack of innovation in recent years is a common topic of discussion with Django. While Django is a stable and mature framework that has been widely used for many years, some developers and businesses may view it as being too rigid and inflexible in terms of keeping up with the latest trends and technologies in web development.
It is lacking innovation in its approach to supporting modern web development paradigms, such as microservices, serverless architectures, and single-page applications. Some developers argue that Django’s traditional Model-View-Controller (MVC) architecture is not well-suited for these modern paradigms, which can lead to a more complex and cumbersome development process.
To compound this, Django has been criticized for lacking innovation is in its approach to supporting real-time, event-driven applications. While Django has some support for WebSockets, it is often viewed as being less flexible and powerful than other modern web development frameworks. It is worth noting that the Django community has been working to address these criticisms and introduce new features and improvements to the framework. For example, the release of Django Channels introduced support for WebSockets and other real-time features, while the introduction of Django REST Framework has made it easier to build RESTful APIs in Django.
Not Suited For Modern Cloud Tech
Similar to the lack of innovation, Django is that it is not well-suited for modern cloud technologies. While Django is a powerful and flexible web framework, some developers and businesses may find that it is not as scalable or performant as some other frameworks when it comes to handling large-scale, high-traffic web applications. Before you tackle me when I say scaling here I mean strictly in the cloud. I know I just finished saying that celery gives it some form of scalability but not as an infra-side friendly one.
Basically the framework’s reliance on a traditional monolithic architecture. This can make it difficult to horizontally scale an application by adding more servers, as the application’s code and data are tightly coupled and spread across multiple tiers of the architecture. Adding to this the complexity of configuring and managing Django applications in a cloud-based environment makes it even harder to take into something like AWS or Azure. While Django is designed to be modular and extensible, it can be challenging to set up and maintain complex infrastructure and deployment workflows that are required for running Django applications at scale in a cloud environment.
It is worth noting that the Django community has been working to address these scalability issues and introduce new features and improvements to the framework. For example, the release of Django Channels introduced support for asynchronous and event-driven programming, which can improve the performance and scalability of Django applications. Additionally, the community has developed many plugins and libraries to help manage deployment and infrastructure, including solutions for containerization and orchestration.
Conclusion
From both the positive and negative list above it should be obvious at this stage that Django is not on a decline. If anything I believe it’s growing it just needs to play a bit of catchup when it comes to the cloud. Since the framework has been very stable and has treated me greatly over the years I will say my biased opinion and say it’s not going anywhere in the next 10 years. The main reason for this is that Python is continuously growing and bring in with it machine learning and other AI technologies with it.
Related
- Is Django Good For Big Projects
- How to do unit testing in Django Rest Framework (Python 3)
- 7 Django extensions that will make your life easy (Python 3)