Django is too complicated!

There is a myth out there on the Internet, a myth that needs to be busted.

It’s the idea that Django is too complicated.

And because it is too complicated, it is too difficult to learn for beginners and also unsuited for small applications or microservices.

Where does this idea come from? I’m not 100% sure but I have a theory and the primary suspect is called settings.py.

Let’s start a Django project to illustrate what I mean. First, we create and activate a virtual environment and install Django:

$ virtualenv venv
$ source venv/bin/activate
(venv)$ pip install Django
Successfully installed Django-2.1 pytz-2018.5

After installing Django, we can use the django-admin.py command which we can use to start our project:

(venv)$ django-admin.py startproject mydjangoproject

Okay, what did that do? It created a directory mydjangoproject. Let’s have a look at the contents of this directory:

(venv)$ tree mydjangoproject
├── manage.py
└── mydjangoproject
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

That looks manageable. Until you open settings.py and get hit by 120 lines of gibberish.

To be fair, about a third of those 120 lines are empty, but there are still 26 distinct settings, some of which are intimidating nested dictionaries. And our app doesn’t even do anything yet!

Compare that to a Hello World app in Flask:

from flask import Flask
app = Flask(__name__)

def hello():
    return "Hello World!"

Six lines of code and we are done!

However, this comparison is not entirely fair. Without a doubt, Django is a massive framework that makes your life a lot easier with a vast amount of features. But it is entirely up to you to decide which of these features you want to use.

If you do not want to use any of Django’s features, you can use it almost like a microframework.

What, you don’t believe me? Here is a fully functional Hello World app in Django:

$ wc -l *.py
       0 __init__.py
       3 settings.py
       6 urls.py
       5 views.py
       5 wsgi.py
      19 total

That looks a lot more manageable! Most notably, settings.py shrank to just only three lines:

ROOT_URLCONF = 'mytinydjangoproject.urls'
SECRET_KEY = 'fpT6ABCJzwtaWHBXFyzgCybDzYyTxyPdaxEynvA7CwrkVBgAPEJJfie^NB&spxGs'

So why does django-admin.py overwhelm you with this giant settings file?

The explanation might lie in the Zen of Python, which says:

Explicit is better than implicit.

Instead of hiding some default settings somewhere in its code, Django generates a settings file with sensible defaults as part of your project. If those defaults don’t suit your use-case, you are free to tailor them to your needs.

With our minimal settings file, you won’t benefit from the majority of Django’s features: database abstraction and a powerful automatic admin interface, template loading and rendering, user management, static file handling, to name a few.

You could start with an empty settings file and add the features you need, but I find it easier to remove the parts I don’t need from the settings file generated by Django.

The inconvenient truth is that web development, in general, is a pretty complicated affair. Django solves many problems that you might not even be aware of.

Take CSRF protection, for example. It is enabled by default when you start a new project and can be a stumbling block, especially if you are a beginner. You have to remember to add the {% csrf_token %} to your forms and might grow some grey hairs before you figure out how to get your AJAX requests to work. I still think that enabling CSRF protection by default makes perfect sense. A novice programmer might not know that CSRF exists, how a CSRF attack works, and much less how to protect against it.

So what’s the final verdict? Is Django too complicated?

As you might have guessed, my answer is No.

If you want to share your opinion, leave a comment below, drop me an email or get in touch on Twitter.

Header image by unsplash-logochuttersnap

Leave a Reply