6 Django Mistakes That Expose You as a Rookie! 🚨

Photo by Francisco De Legarreta C. on Unsplash

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.


Django Developers, Stop Using .all() for Queries – Here’s Why!
Django’s ORM is powerful, but using .all() indiscriminately can lead to performance bottlenecks, unnecessary database…
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)

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!

6 Django Mistakes That Expose You as a Rookie! 🚨 [Part 2]
This is the second part of 6 Django Mistakes That Expose You as a Rookie! 🚨 . If you haven’t checkout the Part 1 do…
Photo by Simone Hutsch on Unsplash