What makes the Django web framework hard to learn?

I’ve given this question a lot of thought recently. As the author of Django for Beginners, I receive regular feedback from readers– both total beginners and those experienced in other programming languages but new to Django–who are struggling. I’m very empathetic since I first learned web development back in 2013 with Django and it was not a smooth road at all.

So what is it? The Django community is very open and collaborative. The official documentation is exceptionally comprehensive. And it’s all written in Python, now the most popular introductory programming language at U.S. universities and the second most popular language on Github behind only JavaScript.

The Positives

Here are Django’s positives in my opinion:

The Negatives

And here are some possible reasons why Django is challenging to learn:

1: Web Development is hard

There is a ton to learn in web development and especially if it’s your first time moving beyond basic Python programming exercises, a newcomer quickly becomes overwhelmed with all the advice to learn git, DNS, HTTP, databases, deployment, security, authentication, and more.

This isn’t Django’s fault–it’s just a web framework–but in the mind of a newcomer, Django gets the blame. Partly this is because Django sits somewhere in the middle on the “magic” scale of frameworks: Rails sits at the top (very little code to get started, strong defaults) while a microframework like, say, Flask or Express, is closer to the bottom.

I appreciate Django being both full of defaults and very customizable, but the latter comes at the cost of complexity. And beginners don’t appreciate it.

2: Lack of beginner-friendly tutorials

Overall the Python and Django community feel much more intermediate/advanced focused than beginner focused. Whereas the Ruby on Rails world is very open and focused on newcomers to programming and web development.

Rails in particular has the fantastic Rails Tutorial that baby-steps through building a simple CRUD application with user accounts and deployment. There are also many, many tutorials written for the total beginner in mind. In Django, what is similar? We have the Django Girls Tutorial, my own at Django for Beginners, and then…it’s largely crickets chirping.

I suspect this divide exists because many developers who know Python learned it in an academic context so their base level of knowledge is higher than someone who has never programmed before and is often pointed to Rails as a result. Or to JavaScript and therefore Express as the first web framework.

I’m doing my own part via tutorials and books because Django really can be beginner-friendly but most content is pointed at more experienced developers.

3: Relatively complicated “Hello, World”

Compared with Flask or Express, creating a simple “Hello, World” takes more work in Django. You need to create a new Django project, a new app, update project-level urls, create app-level urls, and create a view. Here’s a short tutorial for those who want to build their own.

If you’re an experienced Django developer, yes, you don’t have to create an app for a “Hello, World” example, but since the project/app paradigm is used throughout Django it’s less confusing to beginners to just start with this approach.

4: Local development setup

Back in 2016 I taught a college-level class on web development with MeteorJS. It succeeded in large part because Meteor had a one-line installation that provided a full working local dev environment with a configured MongoDB database, and default plugins for user auth among other things. Plus, it was all written in JavaScript. By the end of three short weeks, students had built surprisingly complex web applications.

Django (and most other frameworks) by contrast can be difficult for a beginner to setup. You must install Python 3, then virtual environments, and then install Django. And really you should also download and configure a local database like Postgres rather than the built-in SQLite. It’s a lot.

5: Multiple ways to do the same thing

Django gives developers a lot of flexibility when it comes to structuring a new project (though less than microframeworks like Flask or Express). This is a double-edged sword: I speak from experience when I say it is deeply confusing to read multiple different approaches to basic project setup, let alone more complex cases.

As an example, consider the official polls tutorial which advocates including templates in an app -> templates -> app -> template_name.html format, which is how the Django loader looks by default. That’s fine, but then most real-world projects advocate tweaking your settings.py file and putting all your templates in one project-level templates folder. Or putting project-level templates there but including app-level templates in the app directories.

6: Function-based views vs Class-based views

As an experienced developer I appreciate the fact that Django supports both function and class-based views. But for beginners this just yields to confusion. Which to use? How are they different? When to use which? There is no real consensus online among “the experts” here.

Class-based views are in my opinion a big improvement in Django and seem to be the way things are headed. However…it’s really confusing to have tutorials switch between the two, yet this seems to be the normal way Django is presented. As in, here’s the “real” way to do it with function-based views and here’s the CBV shortcut.

I understand why showing both approaches increases understanding once you’re at a given level. But I think focusing on how simple things can be with CBV is a better up-front approach. Use CBVs and even better Generic Class Based Views to show how little code we need to build common functionality. Then, once the reader has gotten it to work and has some confidence, go deeper with the function-based approach or show how to customize the CBVs. Most tutorials do this backwards.

7: The Urls, Views, Templates dance

It takes a lot of practice to internalize the fact that a single web page often requires a dedicated url, view, and template. Three separate things for one page. Add in the fact that the order in which you build all three doesn’t really matter and things become confusing fast for newcomers.

8: User Model

Django ships with a default User model however in practice most developers will swap in a custom user model from the beginning in order to make changes down the line. This is partly a legacy feature but compared to other web frameworks, messing around with User is a pain.

9: User Registration

Most web frameworks come with a built-in way to do user registration; Django does not. Therefore even a basic Django project requires the developer to either write their own sign-up logic or rely on a 3rd party package like django-allauth. This just adds to confusion for newcomers, though it also allows experienced developers to highly configure things the way they want.

10: Deployment

Django does not provide much hand holding when it comes to deployment. This is an advantage for experienced developers who want the option of using either a Platform-as-a-Service like Heroku/PythonAnywhere/Repl.it or configuring their own server. However for beginners, other frameworks do a better job of making deployment seamless.

Concluding Thoughts

I’ll add to this post over time but for now these are my main thoughts. And to be clear, I’m writing this because I think Django is fantastic and I want to figure out how to share it with more programmers.