6 Django Mistakes That Expose You as a Rookie! 🚨
Photo by Francisco De Legarreta C. on Unsplash

Django is one of the most powerful web frameworks, but even experienced developers sometimes fall into rookie traps that can make their apps slow, insecure, or hard to maintain.
If you want to level up your Django skills and avoid common pitfalls, here are six mistakes that can expose you as a beginner — and how to fix them!
1. Using .all()
Everywhere Without Filtering
The Mistake
Many beginners blindly use .all()
in queries, leading to unnecessary database load.

products = Product.objects.all()
This loads all products into memory — even if you only need one or two!
The Fix
Always filter your queries to fetch only what you need:
products = Product.objects.filter(category="Electronics")
Use .only()
or .values()
for better efficiency:
products = Product.objects.only("name", "price")
Use pagination for large datasets:
from django.core.paginator import Paginator
paginator = Paginator(Product.objects.all(), 10)
page = paginator.get_page(1)
2. Not Using select_related()
& prefetch_related()
The Mistake
Rookies often make too many queries when fetching related objects, causing N+1 query issues.
orders = Order.objects.all()
for order in orders:
print(order.customer.name) # Extra query for each order! ❌
The Fix
Use select_related()
for ForeignKey relationships:
orders = Order.objects.select_related("customer").all()
Use prefetch_related()
for ManyToMany relationships:
books = Book.objects.prefetch_related("authors").all()
This drastically reduces queries and improves performance!
3. Hardcoding Secrets in settings.py
The Mistake
Storing sensitive data like API keys, database passwords, or secret keys directly in settings.py
:
# settings.py
SECRET_KEY = "super-secret-key"
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": "mydb",
"USER": "admin",
"PASSWORD": "mypassword",
}
}
The Fix
Use environment variables and .env
files instead:
SECRET_KEY=kbwclhilewdjleo2djoeiwjdiehduheud
DATABASE_NAME=mydb
DATABASE_PASSWORD=mypassword
DATABASE_USER=admin
DATABASE_HOST=localhost
Use django-environ for better security:
pip install django-environ
Then, in settings.py
:
# settings.py
import environ
env = environ.Env()
environ.Env.read_env()
SECRET_KEY = env("SECRET_KEY")
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": env("DATABASE_NAME"),
"USER": env("DATABASE_USER"),
"PASSWORD": env("DATABASE_PASSWORD"),
"HOST": env("DATABASE_HOST"),
}
}
Never hardcode credentials in your repo!
4. Ignoring Indexes on Large Tables
The Mistake
Not adding indexes to frequently queried fields slows down queries significantly.
class Order(models.Model):
order_number = models.CharField(max_length=100, unique=True) # No index! ❌
customer_email = models.CharField(max_length=255) # Slow searches! ❌
The Fix
Add indexes for faster lookups:
class Order(models.Model):
order_number = models.CharField(max_length=100, unique=True, db_index=True) # âś…
customer_email = models.CharField(max_length=255, db_index=True) # âś…
Use Meta.indexes
for custom indexing:
class Product(models.Model):
name = models.CharField(max_length=255)
category = models.CharField(max_length=100)
class Meta:
indexes = [
models.Index(fields=["name"]),
models.Index(fields=["category"]),
]
This improves query speed dramatically!
5. Not Using Django’s Built-in Security Features
The Mistake
Many beginners skip Django’s built-in security tools, leaving their apps vulnerable to attacks like CSRF, SQL Injection, and XSS.
The Fix
Enable Django’s Security Settings in settings.py
:
# settings.py
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
Use Django’s authentication and permissions instead of rolling your own:
from django.contrib.auth.decorators import login_required
@login_required
def dashboard(request):
return render(request, "dashboard.html")
Always sanitize user input:
from django.utils.html import escape
safe_input = escape(user_input)
Ignoring security features can get your app hacked!
6. Writing Fat Views Instead of Using Services
The Mistake
Many beginners cram all business logic into views.py, making code hard to test and maintain.
# views.py
def checkout(request):
cart = request.session.get("cart", [])
total = sum(item["price"] for item in cart)
user = request.user
order = Order.objects.create(user=user, total=total)
request.session["cart"] = []
return redirect("order_success")
This violates the Single Responsibility Principle (SRP)
The Fix
Move logic into service functions in services.py
:
# services.py
from .models import Order
def create_order(user, cart):
total = sum(item["price"] for item in cart)
order = Order.objects.create(user=user, total=total)
return order
Call the service function in views:
# views.py
from .services import create_order
def checkout(request):
order = create_order(request.user, request.session.get("cart", []))
request.session["cart"] = []
return redirect("order_success")
This makes code cleaner, reusable, and easier to test!
Conclusion
Avoiding these rookie mistakes will make your Django apps faster, more secure, and maintainable.
Want to master Django like a pro? Fix these mistakes today and build high-quality, scalable apps! 🚀
If you enjoyed this article, I’m sure you’ll love Part 2!

