Django is a mature and powerful web application framework that offers a lot of "batteries included" features. It is rather opinionated as to how you use it which takes a lot of cognitive load off the developer.

Adopting Django, or any opinionated framework for that matter, is a lot like any relationship. Yes, there are imperfections and small frustrations, but you will get the most out of it if you commit and invest yourself (and your team) in it.

Pros

Simple Admin on your data

Rich ecosystem of add-ons, plugins, and documentation

Excellent integration with tooling and IDEs

Most things included

Powerful DX (Developer Experience)

Task-runner for command-line and long-running or daemon processes

You can grow into the framework as your needs change

Cons

No framework is perfect, and Django is no exception. Many of these are addressed in the "must-haves" section.

Difficulty in deployment - Django definitely optimized the DX (Developer Experience), but is lacking in how well it is deployed. These days there are services like Heroku or OpenShift. There are also open-source alternatives (Dokku or CapRover) that make it much easier.

Django definitely optimized the DX (Developer Experience), but is lacking in how well it is deployed. These days there are services like Heroku or OpenShift. There are also open-source alternatives (Dokku or CapRover) that make it much easier. User registration - While Django offers some of the plumbing for typical user registration and management, it does not offer the fully-baked workflows with security in mind. That is on you.

- While Django offers some of the plumbing for typical user registration and management, it does not offer the fully-baked workflows with security in mind. That is on you. Dynamic configuration (eg - easy 12-factor) - There is a settings.py file where you keep the configuration for your application, but it is often treated like a static file. One must jump through a few hoops to pull in dynamic configuration settings at start time.

- There is a file where you keep the configuration for your application, but it is often treated like a static file. One must jump through a few hoops to pull in dynamic configuration settings at start time. Changing settings in live environment - Once the Django process is loaded into memory there is no way to change what you had set in the settings.py file. In order to change that you will need to update and restart or re-deploy the service.

Once the Django process is loaded into memory there is no way to change what you had set in the file. In order to change that you will need to update and restart or re-deploy the service. No easy static asset serving in production

The must-haves

The following libraries are the "must haves." They provide the basic tooling and shortcuts that make getting up to speed and deploying 12-factor apps nice and simple.

Django AllAuth

(simple user registration and management)

You want user registration, password reset flows, and oauth2 provider support for many social services? Please consider django-allauth. This addresses Con #1

White Noise

(serve static assets)

This library allows us to serve static assets like images and javascript from within the Django application. It is usually a simple one-liner. It obviates the need to use Nginx or a CDN to deliver these assets. View WhiteNoise here.

DJ Email URL

(Easy configuration for sending email via SMTP)

This little library makes it easy to parse the SMTP credentials string out of the environment variable into a format that Django likes.

DJ Database URL

(Easy configuration for database connection strings)

This library is like the Email one, except it works for configuring your database from a string.

Sentry SDK

Though not required for development, I find Sentry to be an invaluable service for immediate detection of errors in the application. Stack traces and context is sent along with the crash information. I recommend it.

Python Dotenv

This little library makes it easy to load environment variables into your application when developing. If you build using the 12-factor pattern, then this will make more sense. However, this is not used in production because environment variables are passed in at run-time.

Django Bootstrap4

I'm lazy, so I use Bootstrap because it is very opinionated and offers the "kichen sink" when it comes to UI elements. This library is a set of helper functions and templates that make working with bootstrap easier (like form rendering).

Django Solo

This library gives us database singletons – a simple table that holds single values that we can use across the application. It is different that what we put into settings.py because they can be changed at run-time. Think of it like cheap and easy feature-flagging.

Optional, based on needs

The following libraries are my go-to when I need them.

Twilio

If you need to send SMS or build video-chat into your app, this is my go-to. Twilio is huge, so I am only using but a small part of their offerings.

Django Lazy Signup

This library will allow anonymous users to create accounts without giving any information. It is like an "instant trial" if you are building a SaaS. If they convert then then can fill out the required fields to become full users. You can see it in action over here at Curabase.

Django Rest Framework

Last we have Django Rest Framework (DRF). This incredibly deep, well-engineered, and thouroughly documented library makes it easy to add a full REST API to your application.

Escape Hatches for the Future

You never know what you will need in the future, and this is where Django's "batteries included" features shine:

Django Commands for more async or long-running tasks. I have used it to scrape web pages, take screenshots, send SMS/emails to thousands of users.

Django channels for Websockets

Addons for GraphQL

Caching

Translations

The list goes on. I won't belabor it, but you get the idea.

Conclusion

Django by itself is a good choice for starting almost any web project. When combined with a few extra libraries and deep ecosystem it becomes an unbeatable stack when compared to other frameworks.