Django and Ruby on Rails : Which Framework to Choose

Django and Ruby on Rails : Which Framework to Choose

Django and Ruby on Rails : Which Framework to Choose. When thinking about long-term prospects of a technology stack, it’s common to evaluate the strengths of each tech community and compare Django vs. Ruby on Rails popularity among the software developers.

There are more than 90 web-development frameworks out there. No wonder it’s hard to choose the one that’ll suit your project best. Still, there are at least two major frameworks that are widely used by the tech giants of nowadays, and for good reason. Ever heard of Django or Ruby on Rails? If both web frameworks are quite good, how do you compare Django and Ruby on Rails to choose which one to use for web development?

Instagram, YouTube, Spotify, Dropbox, and other online- and app-based services that we use daily are powered by Django, a Python-programming-language framework. On the other hand, Airbnb, Bloomberg, Shopify, and other leading companies use Ruby on Rails, a Ruby programming language framework. Both languages were created to serve the web and make web applications (including mobile web apps) possible.

In this article, we’ll compare these two popular frameworks. While both are fast and easy to use, Django and Ruby on Rails each have reasons for and against them as the development framework for your future project.

As software-development professionals, we’ve found materials comparing Django vs. Ruby on Rails performance and speed too oversimplified, since speed and performance often depend on the complexity of each individual project as well as the proficiency of the development team with the respective technology.

What we mean to say is that even if Python/Ruby/etc. are interpreted languages and are slower in certain workloads for tasks which are relevant for a web framework, this may not matter. So we decided to take a closer look at their pros and cons, as well as use cases to help you decide which one is the best fit for your needs.

Django Pros, Cons, and Use Cases

Django is a widely used Python web development framework. It was developed in the fall of 2003 by Adrian Holovaty and Simon Willison as they started to use Python to build applications. It gained its speed, security, and scalability from Python. Pinterest Engineering, Mozilla, Udemy, NASA, Washington Post, and other powerful websites all rely on Django. It comes with the most tools and libraries for common use cases — for instance, its authentication, URL routing, template engine, object-relational mapper (ORM), and database-schema migrations (Django v.1.7+). In the following sections, we’ll discuss some of the reasons for and against Django.

Django Pros

Some say that Django’s pros outweigh its cons. Let’s take a look at its main advantages:

Rapid and low-cost prototype/MVP development

Django has a flexible, well-structured admin panel that lets you reuse code from one project to another. Besides, there are plenty of out-of-the-box libraries that can help you build a product prototype or an MVP fast.

Explicit, logical syntax

The Django framework is easy to build on, easy to work with, and easy to support. It’s based on Python, which is considered one of the easiest development languages to learn. Besides, it is easy to debug and read, which means it’s not going to be a problem for new team members to catch up with a project midstream.

An extensive open-source ecosystem

Being an open-source ecosystem means that numerous tools and libraries, both free and paid, are available for everyone at any time. Django’s official documentation is more than enough to find solutions if you’re stuck. Besides, there are plenty of helpful forums such as Stack Overflow or the Django community on Reddit, where developers find answers to their Django-related questions.

Django admin portal

This built-in admin panel is a great tool for easier management of the back-end user interface. It is well structured and has permissions and authentication modules out of the box. Besides, it’s easy to customize by adding custom CSS or replacing the default templates.

Django’s REST framework

REST stands for Representational State Transfer, and it lets you easily build APIs. It’s powerful enough to build an API in just three lines of code and flexible enough to return multiple data formats and handle different types of calls. Basically, the Django Rest Framework gives you a lot of conveniences, such as authentication modules, JSON serializers/deserializers, API routing, and documentation. You could argue that when comparing Django vs. Rails performance in an API-heavy project, the REST-based architecture is among the most evident Django/Python Pros.

Django Cons

Although Django has many advantages, there are also a couple of downsides:

Requires more code upfront

Django developers have to write more of the code themselves. As a result, they are more conscious, purposeful, and demanding of the business goal.

Django is monolithic

Django is a full-stack framework with a monolithic approach. Basically, it is the other side of a ready-to-use, out-of-the-box solution. Django pushes developers into certain patterns within a framework. This is also the reason why Django is the choice for large, tightly coupled products. The Django framework is a single package where all components are deployed together, so you can’t pick and choose bits and pieces.

Django Use Cases

Django is widely used for e-commerce websites, healthcare, financial applications, social media sites, transportation, and more. Here are the main areas where Django is applied:

  • Travel and booking systems with complex, fine-tuned customizations
  • Platforms with complex API architecture that rely on data from third parties
  • Content, data, and e-commerce management engines with custom rules
  • Other web apps with dynamically changing complex algorithms
Django Summary Table

Ruby on Rails Pros, Cons and Use Cases

Similarly, Ruby on Rails (RoR) is also an open-source framework. It lets developers use ready-made solutions, helping them save time on programming processes. David Heinemeier Hansson, the founder of Ruby on Rails, powered his own web application Basecamp with the Ruby framework. Other famous websites built with Ruby on Rails include Twitter, GitHub, Yellow Pages, and more. So how does one compare Ruby on Rails vs Django?

Based on the Ruby language, Ruby on Rails inherited its parent’s logic and simplicity. Basically, Rails is a layer on top of Ruby that helps developers build web applications. It’s a very popular choice for backend solutions, and there’s a comprehensive guide called The Rails Way, which helps build production-quality software with Rails.

As a fully fledged framework, it offers an object-relational-mapping (ORM) system for business data and logic, application management, and routing out of the box. It is a popular choice within Silicon Valley (big Valley startups based on RoR are Airbnb, Etsy, Spotify, etc.).

Now we’re going to take a closer look at it to know why.

Ruby on Rails Pros

Ruby on Rails is indeed one of the most popular web-development frameworks. Here are the main benefits of Ruby on Rails:

Component structure based on plugins and gems

Ruby on Rails’ component structure, based on plugins (application level) and gems (system level), lets experienced RoR developers quickly put together efficient applications with less coding. The plugins are well documented and easy to use. New gems are constantly added to public repositories, such as the popular RubyGems resource, which currently contains more than 150,000 total gems for download.

Easy to migrate and modify

In fact, any fundamental changes to the codebase don’t require many changes in the application code. RoR code is of high quality and can be easily read. Ruby on Rails developers don’t have to micromanage it.

Diversity of presets and tools

There are lots of must-have features that are already preconfigured. Ruby on Rails provides developers with multiple standard web features and patterns, which significantly speeds up the development process.

Testing environment

When complex testing logic is the core of the product, RoR’s superior testing environment is a great help. Developers can make sure their apps work as desired using testing and debugging tools, as RoR makes it easy to build automated tests and get all aspects of the product checked.

Ruby on Rails Cons

Along with advantages, come the downsides. Here are some of them:

Faster complexity and tech-debt buildup

Ruby on Rails’ flexibility has a downside. Basically, with so many ways to code the same outcome, code can get difficult to read and may require a steeper learning curve as well as more rework later on.

More difficult-to-create API

Building an API with Ruby on Rails can be incredibly complex, as RoR has no equivalent to Django’s REST framework.

Documentation quality and standards vary

With Ruby on Rails, it may be hard to find good documentation, especially for less popular gems. Most of the time, there are test suites that serve as the main source of information for developers. They have to study the code instead of simply reading the official documentation (which is not there).

Ruby on Rails Use Cases

RoR is widely used for creating prototypes and MVPs. On top of that, it’s very popular in the startup community. According to SimilarTech, more than 402,000 websites are powered with RoR. Here’s an overview of the main areas where Ruby on Rails is used:

  • Relatively self-sufficient systems without much third-party data exchange
  • Platforms with dynamically changing rules that need to be retested frequently
  • Content, data, and e-commerce management engines with relatively standard feature-set requirements
  • Other CPU-intensive web apps
Ruby on Rails Summary Table

Django Framework vs. Ruby on Rails Framework Comparison

Both Django and Ruby on Rails are great web development frameworks. They can deliver modularized, clean code and significantly reduce the time spent on common web-development activities. Both of them follow the model-view-controller (MVC) principle, which means modeling of the domain, presenting the application data, and user interaction, all work separately from each other. The question then is: How do you pick which framework to use?

The decision may come down to which language you prefer or which software development principle you want to follow: to rely on sensible defaults, such as Ruby’s convention-over-configuration principle, or to follow Python’s explicit-is-better-than-implicit principle. The answer is simple — you can’t really go wrong by picking either one.

Here’s a comparison table of the two frameworks as a reminder of the main attributes of each:

When thinking about long-term prospects of a technology stack, it’s common to evaluate the strengths of each tech community and compare Django vs. Ruby on Rails popularity among the software developers. In fact, there is no perfect front-end framework out there. Your choice should always rely on your business goals and objectives.

The framework of your choice should serve your business needs and fit into the industry ecosystem — and not because of hype, your friend’s advice, or ease of hiring, but because it suits your project’s objectives. Study the purpose of a framework beforehand, as some frameworks are a good fit for gaming applications, while others, for example, lean toward e-commerce websites.

You should approach this fundamental decision carefully and strategically. It’s hard to simply switch programming platforms in the middle of development, as it takes time, is risky, and is also quite expensive. So choose the main platform, but consider whether its core library is flexible and adaptable, in case you need to make any modifications in the future.

On top of that, deciding what framework to use is a strategic investment for the company. It should not be solely a CTO or an IT department’s decision but rather one that considers the elements of the desired framework at all levels.

Python Django Tutorial | Django Course

Python Django Tutorial | Django Course

🔥Intellipaat Django course: https://intellipaat.com/python-django-training/ 👉This Python Django tutorial will help you learn what is django web development &...

This Python Django tutorial will help you learn what is django web development & application, what is django and introduction to django framework, how to install django and start programming, how to create a django project and how to build django app. There is a short django project as well to master this python django framework.

Why should you watch this Django tutorial?

You can learn Django much faster than any other programming language and this Django tutorial helps you do just that. Our Django tutorial has been created with extensive inputs from the industry so that you can learn Django and apply it for real world scenarios.

Developing Restful APIs with Python, Django and Django Rest Framework

Developing Restful APIs with Python, Django and Django Rest Framework

This article is a definitive guide for starters who want to develop projects with RESTful APIs using Python, Django and Django Rest Framework.

This article is a definitive guide for starters who want to develop projects with RESTful APIs using Python, Django and Django Rest Framework.

Introduction
  • Django is a web framework written in Python
  • Python is an interpreted high-level programming language for general-purpose programming
  • API or Application Programming Interface is a set of rules and mechanisms by which one application or component interacts with the others
  • REST or Representational State Transfer is a software architecture

REST APIs

As described in a dissertion by Roy Fielding,

REST is an "architectural style' that basically exploits the existing technology and protocols of the web.
In simple definition, it is the data representation for a client in the format that is suitable for it.

Hence, RESTful + API is a commonly used terminology for the implementation of such architecture and constraints (eg. in web services).

Here is an example GET request from GitHub's API

$ curl https://api.github.com/users/joshuadeguzman

You will see an output similar to this

{
  "login": "joshuadeguzman",
  "id": 20706361,
  "node_id": "MDQ6VXNlcjIwNzA2MzYx",
  "avatar_url": "https://avatars1.githubusercontent.com/u/20706361?v=4",
  "gravatar_id": "",
  "url": "https://api.github.com/users/joshuadeguzman",
  "html_url": "https://github.com/joshuadeguzman",
  "followers_url": "https://api.github.com/users/joshuadeguzman/followers",
  "following_url": "https://api.github.com/users/joshuadeguzman/following{/other_user}",
  "gists_url": "https://api.github.com/users/joshuadeguzman/gists{/gist_id}",
  "starred_url": "https://api.github.com/users/joshuadeguzman/starred{/owner}{/repo}",
  "subscriptions_url": "https://api.github.com/users/joshuadeguzman/subscriptions",
  "organizations_url": "https://api.github.com/users/joshuadeguzman/orgs",
  "repos_url": "https://api.github.com/users/joshuadeguzman/repos",
  "events_url": "https://api.github.com/users/joshuadeguzman/events{/privacy}",
  "received_events_url": "https://api.github.com/users/joshuadeguzman/received_events",
  "type": "User",
  "site_admin": false,
  "name": "Joshua de Guzman",
  "company": "@freelancer",
  "blog": "https://joshuadeguzman.me",
  "location": "Manila, PH",
  "email": null,
  "hireable": true,
  "bio": "Android Engineer at @freelancer. Building tools for humans.",
  "public_repos": 75,
  "public_gists": 2,
  "followers": 38,
  "following": 10,
  "created_at": "2016-07-28T15:19:54Z",
  "updated_at": "2019-06-16T10:26:39Z"
}

Shown above is a data set in JSON format.

JSON or JavaScript Object Notation is an open-standard file format that uses human-readable text to transmit data objects consisting of attribute–value pairs and array data types.
Other formats include XML, INI, CSV, etc. But today, JSON is widely use for its structure is intuitive, making it comfortable to read and map domain objects no matter what programming language is being used.

Python and Django

Python, according to its creator, Guido van Rossum, is a

high-level programming language, and its core design philosophy is all about code readability and a syntax which allows programmers to express concepts in a few lines of code.
Python uses english like words representation (eg. for methods, reserve keywords and control flow) that makes it easier for any beginner to jump right into it. It also features dynamic type system meaning it verifies the type safety of program at runtime. It also does automatic memory management.

print(5 + 5) # This will result to 10

Django is a high-level Python Web Framework that enables developers to deliver projects on time with clean and pragmatic design.

Its flagship features include a design for fast development, a secure and scalable product.

Quick Django Overview

Django's way of propagating changes to your database schema is by means of its migration modules.

Sample User model

from django.db import models

class User(models.Model):
    first_name = models.CharField(max_length=50)
    middle_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

If any changes are made on your models, run makemigrations

$ python manage.py makemigrations

Finally, you can synchronize the database with the set of models and migrations

$ python manage.py migrate

REST APIs with Django Rest Framework

DRF or Django REST Framework is a powerful and flexible toolkit for building Web APIs. It helps the developers to not reinvent the wheel by rolling out complex and solid REST API from scratch by themselves. Because when your projects become more and more complex, you will soon realise the need of using DRF or other helpful rest framework.

1. Installation & Project Setup

Create project directory

$ mkdir djangoapi

Install virtualenv via pip

A virtual environment enables a project to have additional libraries or changes in packages within its environment without disturbing global or libraries of other environments.

pip is a package management system used to install and manage software packages written in Python.

$ pip install virtualenv

To create an environment folder in your project's directory

$ cd djangoapi
$ virtualenv venv

To activate the environment

$ source venv/bin/activate

To undo these changes to your path, simply run deactivate. More on virtualenv.

Install django, djangorestframework

$ pip install django
$ pip install djangorestframework

Creating a django project

$ django-admin startproject blog

Running your project

$ python manage.py runserver

System check identified no issues (0 silenced).

You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

August 16, 2018 - 09:58:36
Django version 2.1, using settings 'blog.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

The unapplied migrations refer to the default migration files included when you start a django project.

To synchronize these migration files, simply run migrate

$ python manage.py migrate

Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying sessions.0001_initial... OK

The default database in our project is currently set to SQLite named db.sqlite3.

Creating a django project's app

$ cd blog
$ python manage.py startapp posts

The project structure should look like

$ find .
./posts
./posts/migrations
./posts/migrations/__init__.py
./posts/models.py
./posts/__init__.py
./posts/apps.py
./posts/admin.py
./posts/tests.py
./posts/views.py
./db.sqlite3
./blog
./blog/__init__.py
./blog/__pycache__
./blog/__pycache__/settings.cpython-36.pyc
./blog/__pycache__/wsgi.cpython-36.pyc
./blog/__pycache__/__init__.cpython-36.pyc
./blog/__pycache__/urls.cpython-36.pyc
./blog/settings.py
./blog/urls.py
./blog/wsgi.py
./manage.py

2. Model

Each model instance is a definitive source of the information about your data. In general, each model pertains to a single table in your database.

# djangoapi/blog/posts/models.py
from django.db import models

# Create your models here.

class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()
    is_featured = models.BooleanField(default=False)

    def __str__(self):
        return self.name

__str__ is called by the str() built-in function and by the print statement to compute the "informal" string representation of an object.
If you try running makemigrations, django won't see those changes yet.

$ No changes detected

To solve this, add your posts app to your project's installed apps.

# djangoapi/blog/blog/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'posts' # Add it here
]

To continue with the migration of models

$ python manage.py makemigrations

Migrations for 'posts':
  posts/migrations/0001_initial.py
    - Create model Post

$ python manage.py migrate

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, posts, sessions
Running migrations:
  Applying posts.0001_initial... OK


3. Serialization

Serializers allow data structure or object state to be translated into a format that can be stored or transmitted and be reconstructed later on.

Create API's serializers.py and views.py files and isolate them like this

# posts/api
posts/api/serializers.py
posts/api/views.py

# posts/migrations
posts/migrations/

# posts
posts/admin.py
posts/apps.py
posts/models.py
posts/tests.py
posts/views.py
# posts/api/serializers.py

from ..models import Post
from rest_framework import serializers

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ('title', 'content', 'is_featured') # if not declared, all fields of the model will be shown

In this tutorial we have used ModelSerializer, more on this.

4. Views

A view function, or view for short, is a Python function that takes a Web request and returns a Web response.

# posts/api/views.py

from ..models import Post
from . import serializers
from rest_framework import generics, status
from rest_framework.response import Response

class PostListView(generics.ListAPIView):
    queryset = Post.objects.all()
    serializer_class = serializers.PostSerializer

As seen above, ListAPIView is used for read-only endpoints to represent a collection of model instances.

In this code snippet, we use generics view methods from the rest_framework, more on this.

5. URLs

This is where we setup our routes or URL paths to our designated views in which we expect specific responses for each.

# posts/urls.py

from django.urls import path
from . import views
from .api import views

urlpatterns = [
    path('', views.PostListView.as_view(), name=None)
]

6. Finalizing Setup

Ensure that the rest_framework is added to our project's apps.

# djangoapi/blog/blog/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework', # Add it here
    'posts'
]

7. Django Admin

Since we haven't setup our POST requests yet, we will be populating the database through django's admin panel.

To do that, create a superuser account admin with password 1234password.

$ python manage.py createsuperuser --email [email protected] --username admin

Password:
Password (again):
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

Register the model in the admin panel.

# posts/admin.py

from django.contrib import admin
from .models import Post

# Register your models here.
admin.site.register(Post)

That's it. Visit the admin panel and update posts model's records. More on this.

8. Testing our API

$ python manage.py runserver
GET /api/v1/posts/
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "title": "Example Post #1",
        "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "is_featured": false
    },
    {
        "title": "Example Post #2",
        "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        "is_featured": true
    }
]

Great. Now it's time for us to update our views and finish the standard CRUD operations.

9. Adding more views

POST is a method used for creating (sometimes updating) a resource in the database.

# posts/api/views.py

from ..models import Post
from . import serializers
from rest_framework import generics, status
from rest_framework.response import Response

class PostCreateView(generics.CreateAPIView):
    queryset = Post.objects.all()
    serializer_class = serializers.PostSerializer

    def create(self, request, *args, **kwargs):
        super(PostCreateView, self).create(request, args, kwargs)
        response = {"status_code": status.HTTP_200_OK,
                    "message": "Successfully created",
                    "result": request.data}
        return Response(response)

Most often, we separate List and Create view classes when we want to expose a list of data set while easily preventing a certain request to POST or create a resource in the database for that specific List view.

Usecase always varies for apps, you are opt to use ListCreateAPIView or even ViewSets for combining the logic for a set of related views.

Optional: Since we want to display the data in a more systematic way, we override create method and map our inline custom response handler.

Adding more views with methods GET, PATCH, DELETE to handle a specific blog post detail.

class PostDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Post.objects.all()
    serializer_class = serializers.PostSerializer

    def retrieve(self, request, *args, **kwargs):
        super(PostDetailView, self).retrieve(request, args, kwargs)
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        data = serializer.data
        response = {"status_code": status.HTTP_200_OK,
                    "message": "Successfully retrieved",
                    "result": data}
        return Response(response)

    def patch(self, request, *args, **kwargs):
        super(PostDetailView, self).patch(request, args, kwargs)
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        data = serializer.data
        response = {"status_code": status.HTTP_200_OK,
                    "message": "Successfully updated",
                    "result": data}
        return Response(response)

    def delete(self, request, *args, **kwargs):
        super(PostDetailView, self).delete(request, args, kwargs)
        response = {"status_code": status.HTTP_200_OK,
                    "message": "Successfully deleted"}
        return Response(response)

10. Updating URLs

# posts/urls.py

from django.urls import path
from . import views
from .api import views

urlpatterns = [
    path('', views.PostListView.as_view(), name=None),
    path('create/', views.PostCreateView.as_view(), name=None),
    path('<int:pk>/', views.PostDetailView.as_view(), name=None)
]

Now you can send requests to your API via Postman, your app or do a GETrequests from your browser, examples:

POST /api/v1/posts/create/
HTTP 200 OK
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "status_code": 200,
    "message": "Successfully created",
    "result": {
        "csrfmiddlewaretoken": "rnSUN3XOIghnXA0yKghnQgxg0do39xhorYene5ALw3gWGThK5MjG6YjL8VUb7v2h",
        "title": "Creating a resource",
        "content": "Howdy mate!"
    }
}
GET /api/v1/posts/1/
HTTP 200 OK
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "status_code": 200,
    "message": "Successfully retrieved",
    "result": {
        "title": "Sample Post",
        "content": "Sample Post Content",
        "is_featured": false
    }
}

That's it. You have successfully managed to develop RESTful APIs with DRF! Cheers!

Source code

Available on GitHub.