Whether you are looking to decide the web framework for your next project or you are considering trying out AdonisJs or Django in general, this article will give you an idea of what to expect from both of them.
AdonisJs and Django are both full-stack web development frameworks with similar and unique features, making them suitable for certain types of projects. In this article, we’ll take a closer look at the comparison between the two frameworks.
According to the AdonisJs website:
AdonisJs is a Node.js MVC framework that runs on all major operating systems. It offers a stable ecosystem to write server-side web applications so you can focus on business needs over finalizing which package to choose or not. AdonisJs favors developer joy with a consistent and expressive API to build full-stack web applications or micro API servers.
And the Django website describes Django as:
A high-level Python web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source.
In short, while you can use both AdonisJs and Django to build any kind of application, I prefer to use Django for content management-related apps and AdonisJs for SaaS-based apps.
Now, let’s see what it takes to set them up.
Setting up AdonisJs is easy. Because it’s a Node.js-based web framework, you must have Node.js and npm installed.
You can set it up with either the CLI, npx, or by using Git commands.
To set up AdonisJs using the CLI, you’ll need to install the CLI globally first by running the below command on your terminal:
npm install -g @adonis/cli
It might take a while depending on the strength of your internet connection. When it’s done, you’ll be able to run adonis new musicplayer
on your terminal to create a new Adonis application called musicplayer
.
To use Git to install AdonisJS, you must have Git installed. Now, run any of the commands below.
# Fullstack > git clone --dissociate <https://github.com/adonisjs/adonis-fullstack-app> # API > git clone --dissociate <https://github.com/adonisjs/adonis-api-app> # Slim > git clone --dissociate <https://github.com/adonisjs/adonis-slim-app>
In the above Git commands, AdonisJs comes fully packed with three types of apps: an API version (if you only need to build an API), a slim version (without the API), or fullstack (everything AdonisJs has). It’s up to you to decide which one to set up.
More so, to process other command line tasks with AdonisJs, Adonis comes with a CLI called Ace. Ace is a powerful tool created to make building and maintaining AdonisJs applications easy and fun.
Django is a Python web framework, which means we’ll need to install Python first before installing Django. We’ll use the Python package manager pip to install Django, as shown below:
pip install Django
Once Django is installed, you can then use the Django command-line tool django-admin
to create your first project.
django-admin startproject school_portal
Got your first project up and running?
Awesome. You’ll also need to create your first app for this project because Django allows you to create re-usable applications with the concept of apps. You can have as many apps as you need.
Django provides a script in the file called manage.py
. With this script, you can automate everything that Django allows you to, such as make migrations, log into dJango shell, and the like.
You can use the startapp
command to create a new app as shown below:
python manage.py startapp student
Also, it’s important to note that Django uses the Python virtual environment concept to create projects in isolated environments. So, for most of it, you’ll need to install and activate the Python virtual environment before running these commands.
Unlike AdonisJs, Django doesn’t have an API installation. However, it integrates well with the Django Rest Framework package, in case you want to build an API with Django and there is no minimal Django installation.
Django is known for having “batteries included” — everything you need to get your project up and running as soon as possible.
Generally, the Django’s setup is a bit more involved than that of AdonisJs.
While AdonisJs uses the popular MVC (Model View Controller) architecture, Django uses a slightly unique MVT(Model View Template) design. We’ll see how it all comes together in the next section.
Both frameworks use their model definition in different fashions. The Django model describes all that there is about an entity. You’ll normally update it in case there is need to.
But the AdonisJs model is different. It only defines the model’s class name, extends the model API, and then exports the model.
Most of the work Django does in the model is done at the migration level for AdonisJs.
Here is an example of a Django database model. Note that you’ll have to create this model as you wish by hand.
from django.db import models class Movie(models.Model): title = models.CharField(max_length=100, unique=True) year = models.DateField(auto_now=False, auto_now_add=False) length = models.IntegerField(null=True, blank=True) director_name = models.CharField(max_length=150, null=True, blank=True) language = models.CharField(max_length=100, null=True, blank=True) class Meta: db_table = "movie" def __str__(self): return self.title
You could use the Django database inspectdb tool to generate a model from a legacy database.
python manage.py inspectdb > models.py
This can be handy if you are moving your current application stack to Django.
Here’s an example of an AdonisJs data model:
'use strict' const Model = use('Model') class Movie extends Model { } module.exports = Movie
To create this model, run the command on a terminal inside your project root directory:
./ace make:model Post
The rest of the model definition will be done in the migration file.
Django uses the Django Template Language (DTL) to create templates — the ”T” in its MVT. This templating engine is similar to Jinja and allows you to write Python code inside the template HTML files and has supports for file splitting.
It usually has a base template file that can be extended to create other page layouts. It’s very flexible to work with and expressive.
Here is a Python sample code in a Django template:
{% for party in parties%} <div class="form-check mb-2"> <input class="form-check-input" type="radio" id="party" name="hello" value={{ party}}> <label for="{{party}}">{{ party}}</label> </div> {% endfor %}
Like Django, AdonisJs comes pre-packaged with the Edge Templating Engine. Here is an example of how it looks.
@if(username) <h1> Hello {{ username }} </h1> @else <h1> Hello anonymous </h1> @endif
Did you notice the mustache-like syntax in both of them — {{ }}
? AdonisJs and DTL use the mustache syntax in some way to process dynamic JavaScript content — in the form of interpolation inside HTML.
Django’s view offers a different function from what a view does in a traditional MVC framework like Adonis, Laravel, etc. Django’s view is where you write your application’s business logic.
Here is an example of what a Django view looks like:
def index(request): users = User.objects.all() context = {"parties": users} return render(request, "user/index.html", context)
Django doesn’t have controllers, but Adonis does. For Django, as we stated earlier, you write all your business logic in the views.py file. But Adonis has a controller that does what it should — respond to HTTP requests, delegate tasks to the appropriate services, and process business logic as well.
Here is an example of an AdonisJs controller:
const User = use('App/Model/User') class UsersController { * index (request, response) { const users = yield User.all() yield response.sendView('users.list', {users: users.toJSON()}) } }
One of the best features of Django and AdonisJs is their expressive ORMs (Object Relational Mappers) that allow you to interact with your database without actually writing real database-specific queries.
Even when you decide to change your database, you won’t need to re-write your entire queries again. Just install the database driver for that specific database, make migrations, and boom! Your app is live again.
Django takes this further by allowing you to use raw queries in case your query is too complex and can’t fit into the existing query API.
Adonis ORM is called Lucid and it’s designed with the active record design pattern, the same as Django ORM. Lucid makes use of Knex.js — a “batteries included” SQL query builder for Postgres, MSSQL, MySQL, MariaDB, SQLite3, Oracle, and Amazon Redshift — internally. This means that Lucid support these databases.
Django ORM also supports a wide range of databases such as PostgreSQL, MariaDB, MySQL, Oracle, and SQLite.
You may have noticed how we previously used both ORMs to query the user table in both frameworks.
Here it is again. For Lucid:
const users = yield User.all()
For Django ORM
users = User.objects.all()
Unlike Django, AdonisJs offers clean documentation with use-case examples. Don’t get me wrong, Django’s documentation isn’t bad, but, in my opinion, Adonis does it cleaner and better. In fact, in some parts of the documentation, there are videos to help with understanding concepts and implementations.
The learning curve for both frameworks can be described as gentle. If you already know JavaScript/Node.js and are familiar with MVC design pattern, picking up AdonisJs won’t be difficult.
For Django, if you’re already familiar with Python, it won’t be difficult to get up and running. As you keep learning and building on it, it becomes easy.
AdonisJS has a growing community of developers because it was started about 13 years (2015) after Django was created (2003). As of this writing, Django has over 55.1k stars on GitHub while Adonis has about 9.4k stars.
Web security is a tough job. But the good news is that AdonisJs and Django both take security seriously. So, they are designed to be secured. Let’s see some security implementation in both of them.
1.) SQL injection: The Django ORM properly takes care of any form of SQL injection by escaping any parameter the user controls. This is usually a benefit for using an ORM, as it handles this for you. This behavior is also applicable to AdonisJs as it uses proper ORM as well.
However, as we’ve previously seen, Django allows you to write raw query if you want to. But if you are not careful to escape the parameters within the user’s control, you might open doors for SQL injections.
2.) Cross-site scripting (XSS) attacks and more: Adonis as a framework has a built-in Shield middleware that helps prevent your application from most of the known attacks like XSS, content sniffing, and script injection. It also has implementations for CORS (cross-origin resource sharing) and CSRF (cross-site request forgery) middlewares separately.
Django does implement most of these security measures internally as well. As for brute force attacks, both Adonis and Django do not implement this by default. You’ll have to use an external plugin to do this.
While the framework is helping you with most of the work with the security of your application, it’s important you also follow best practices to ensure your application remains secure.
AdonisJS and Django both come with a robust authentication system. You no longer have to worry about password hashing or other troubles you typically encounter when starting a new project.
In general, AdonisJs authentication is more feature-packed because it also provides a persona middleware that allows you to work with user profiles effectively. For some of the tasks that AdonisJs is capable of performing internally, you’ll have to use an external library like Django Allauth to manage them in Django.
Django user auth might also give you some trouble if after you begin building your app you want to customize how your authentication works because it will take some complex work to perform.
There is a custom user model but that is usually used when you are starting a new project. AdonisJs is more flexible and forgiving with this.
Routing is an essential part of every framework. AdonisJs and Django have their unique ways of handling routing and group routing.
Here is a simple Django route:
urlpatterns = [ path('books/', views.book_index), ]
Here’s one for AdonisJs:
Route.get('posts', 'PostController.index')
If you want to group similar routes, AdonisJs provides a Route.group
API for you:
// Grouped Route.group(() => { Route.get('users', closure) Route.post('users', closure) }).prefix('api/v1')
To implement something similar with Django, you’ll have to use the Django URL namespace. Namespacing in Django URLs allows you to identify a group of URLs with a common URL name or attribute.
urlpatterns = [ re_path('weblog/', include('blog.urls')), path('books/', views.book_index), ]
All the URLs within the blog
app will have the attribute weblog
.
When it comes to sub-domains routing, AdonisJs supports it out of the box. For example, I can easily have a domain like eze.logrocket.com
in my AdonisJs application without sweating it.
It’s as simple as shown below:
Route.group(() => { Route.get('/', ({ subdomains }) => { return `The username is ${subdomains.user}` }) }).domain(':user.myapp.com')
Django doesn’t have this feature. If you were to build a multi-tenant application, this will be a handy feature and a good reason to use AdonisJs.
Since AdonisJs runs on Node.js, it uses the npm package manager to manage dependencies. So, you can define all your dependencies in the package.json
file.
Django uses the Python dependency management file requirement.txt
to define all the application dependencies.
If you are looking to start using Django from day one, Django comes with a content management system that’s fully set up with authentication, permissions, and group permissions. You just have to create a super admin password. AdonisJs doesn’t have this particular feature. Although Django is awesome with all the batteries included, I find myself needing to hack stuff more than I care to.
AdonisJs and Django are two very powerful web development frameworks. They both have their pros and cons. In the end, they are just tools, and, depending on your project type, interest, and preferred stack, you’ll decide the best fit for your project.
You’ll have to accept the faults and maybe augment with other tools from the community or the ones you will build and also enjoy the best parts of these frameworks as well.
Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third-party services are successful, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens while a user interacts with your app. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.
LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. Start monitoring for free.
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 nowBuild scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.
Deno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]
6 Replies to "AdonisJs vs. Django: Which web framework should you use?"
I would also mention one of the greatest features in Django which is its awesome admin dashboard. You can create nice admin interfaces out of the box without writing many code lines and without code generation. Sometimes this is important time saver.
What a nice article, thank you.
After reading your post, i’m still thinking on whether i should use symfony or loopback
I’d prefer a comparison of frameworks in the same language.
Like Django and Flask or Adonis and Nest or Laravel and others.
I will use Expresswebjs over Adonis for nodejs