3 Views

Django Interview Questions Django Tutorial Django ORM Django Middleware Django Forms Django CSRF Protection Django Admin Panel Django Deployment Python Web Development

Top 25 Django Interview Questions and Answers (Beginner to Intermediate)

Image
1. What is Django?

Django is a high-level, open-source Python web framework designed to help developers build secure, scalable, and maintainable web applications quickly. It follows the MVT (Model-View-Template) architectural pattern and emphasizes the principle of "Don't Repeat Yourself (DRY)", encouraging reusable and efficient code.

Originally developed to handle high-pressure newsroom deadlines, Django was built to move projects from concept to deployment rapidly while maintaining clean architecture and strong security standards. It abstracts much of the repetitive web development tasks such as authentication, URL routing, session management, database operations, and admin dashboards.

Core Features:
  • Powerful built-in ORM (Object Relational Mapper)
  • Automatic Admin Interface
  • Authentication & Authorization system
  • Built-in security protections (CSRF, XSS, SQL Injection, Clickjacking)
  • Scalable architecture suitable for high-traffic applications
  • Reusable app-based modular structure

Django is considered a "batteries-included framework", meaning it provides most tools required for web development out of the box - unlike micro-frameworks where developers must integrate third-party packages for core functionality.

Django was first released in 2005 and is maintained by the Django Software Foundation. It powers large-scale platforms such as Instagram, Pinterest, and Disqus - proving its ability to handle millions of users efficiently.
2. What is MVT Architecture in Django?

Django follows the Model-View-Template (MVT) architectural pattern, which is a variation of the traditional MVC (Model-View-Controller) pattern. MVT separates application logic, user interface, and data handling to promote clean code organization and maintainability.

The three main components of MVT are:

  • Model: Represents the data layer. Models define the database schema using Python classes. Django’s ORM automatically translates these models into database tables and provides query methods to retrieve, insert, update, and delete data.
  • View: Acts as the business logic layer. A view receives an HTTP request, processes data (often interacting with models), and returns an HTTP response. Views decide what data is displayed and which template should render it.
  • Template: Handles the presentation layer. Templates use Django Template Language (DTL) to render dynamic data into HTML. They keep UI separate from backend logic.

Request Flow in MVT:

  1. User sends a request via browser.
  2. Django URL dispatcher maps the request to a View.
  3. The View interacts with the Model (if needed).
  4. The View passes data to a Template.
  5. The Template renders HTML and returns the response to the user.
Key Difference Between MVT and MVC:
In traditional MVC, the Controller manages request handling. In Django, the framework itself handles the controller responsibilities (URL routing, middleware, request handling). Therefore, Django's "View" acts more like the Controller in MVC.

This separation ensures:

  • Better scalability
  • Cleaner codebase
  • Easier team collaboration (frontend/backend separation)
  • Reusable modular apps
Interview Tip: If asked “Is Django MVC or MVT?”, say: Django follows MVT, but conceptually it is a variant of MVC where Django internally handles the controller logic through its URL dispatcher and middleware system.
3. What is a Django Project?

A Django Project is the top-level container that holds the entire web application configuration. It defines global settings, URL routing rules, middleware stack, installed applications, and deployment configurations.

When you create a Django project, Django generates a structured directory that acts as the central configuration hub for your application.

django-admin startproject myproject

This command creates the following structure:

myproject/

├── manage.py
└── myproject/
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        ├── asgi.py
        └── wsgi.py

Key Files Explained:

  • manage.py – Command-line utility to interact with the project.
  • settings.py – Contains global configuration (database, installed apps, middleware, static files, security settings).
  • urls.py – Main URL dispatcher that routes incoming requests.
  • wsgi.py – Entry point for WSGI-compatible web servers (used in traditional deployments).
  • asgi.py – Entry point for ASGI servers (supports async, WebSockets, real-time features).
Project vs App:
Project is the overall application container.
An App is a modular component inside the project that handles a specific feature (e.g., blog, payments, users).

A single Django project can contain multiple apps. This modular design promotes reusability and clean architecture. For example, you can reuse a "blog" app in multiple different Django projects.

In production environments, the project configuration plays a critical role in:

  • Security settings (DEBUG, ALLOWED_HOSTS)
  • Database configuration
  • Middleware order
  • Static and media file handling
  • Deployment server configuration
Interview Tip: A Django project is not just a folder - it is the configuration backbone that wires together apps, middleware, URL routing, and deployment entry points (WSGI/ASGI).
4. What is a Django App?

A Django App is a modular, reusable component within a Django project that is responsible for a specific functionality. Instead of building one large monolithic system, Django encourages developers to divide the application into smaller, self-contained apps.

Each app handles one core feature such as authentication, blog management, payments, user profiles, or notifications. This modular design makes the codebase clean, scalable, and reusable across multiple projects.

python manage.py startapp blog

This command generates a default app structure:

blog/
├── __init__.py
├── admin.py
├── apps.py
├── migrations/
├── models.py
├── tests.py
├── views.py
└── urls.py (optional, created manually)

Key Files Explained:

  • models.py – Defines database tables using Django ORM.
  • views.py – Contains request-handling logic.
  • admin.py – Registers models for Django Admin panel.
  • apps.py – App configuration metadata.
  • migrations/ – Tracks database schema changes.
  • tests.py – Unit and integration tests.
Best Practice: Keep apps single-purpose and loosely coupled. If an app becomes too large, split responsibilities into multiple apps.

Project vs App (Common Interview Question):

  • Project is the complete website configuration.
  • An App is a functional module inside the project.

Multiple apps can exist inside one project, and a single app can be reused across different Django projects. This is one of Django’s strongest architectural advantages.

Before an app becomes active, it must be added to the INSTALLED_APPS list inside settings.py. Django then loads its models, admin configurations, and signals automatically.

Interview Tip: A Django app is not a standalone server. It depends on a Django project to run. Think of an app as a “plug-in module” that extends project functionality.
5. What is manage.py?

manage.py is a command-line utility automatically created when you start a Django project. It acts as a wrapper around Django’s django-admin tool and allows developers to interact with the project environment.

It is used to execute various administrative tasks such as running the development server, creating migrations, applying migrations, creating superusers, opening the Django shell, and executing custom management commands.

python manage.py runserver

Common Commands:

  • runserver – Starts the development server
  • makemigrations – Generates database migration files
  • migrate – Applies migrations to the database
  • createsuperuser – Creates admin user
  • shell – Opens interactive Django shell

Internal Working:

The most important role of manage.py is setting the DJANGO_SETTINGS_MODULE environment variable automatically. This tells Django which settings file to load before executing any command.

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")

This ensures all project-specific configurations (database, apps, middleware, etc.) are loaded correctly before any operation runs.

Difference Between django-admin and manage.py:
django-admin is a global command-line tool.
manage.py is project-specific and automatically links to your project’s settings.

When you run runserver, Django initializes the app registry, loads middleware, connects to the database, and starts a lightweight WSGI development server.

Interview Tip: manage.py is essentially a thin wrapper over django-admin that configures the project environment before executing commands.
6. What is settings.py?

settings.py is the central configuration file of a Django project. It defines how the project behaves, which applications are active, how the database connects, how middleware is executed, and how static/media files are handled.

Every Django project must have a settings module, and it is automatically loaded when the project starts via the DJANGO_SETTINGS_MODULE environment variable.

Key Configuration Sections:

  • SECRET_KEY – Cryptographic key used for session signing, CSRF protection, and password reset tokens.
  • DEBUG – Enables detailed error pages in development.
  • ALLOWED_HOSTS – Defines which domains can serve the application (important in production).
  • INSTALLED_APPS – List of all apps enabled in the project.
  • MIDDLEWARE – Ordered list of middleware classes executed during request/response cycle.
  • DATABASES – Database configuration (SQLite, PostgreSQL, MySQL, etc.).
  • TEMPLATES – Template engine configuration.
  • STATIC_URL / STATIC_ROOT – Static file settings.

Example Database Configuration:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'mydb', 'USER': 'myuser', 'PASSWORD': 'mypassword', 'HOST': 'localhost', 'PORT': '5432', } }
Security Best Practice: Never commit your SECRET_KEY, database passwords, or API credentials to public repositories. Use environment variables instead.

How Django Uses settings.py Internally:

When the project starts, Django loads settings before initializing:

  • App registry
  • Database connections
  • Middleware stack
  • Template engines
  • Authentication backends

The order of middleware in MIDDLEWARE is critical because requests pass through middleware top-down and responses pass bottom-up.

Production Considerations:

  • Set DEBUG = False
  • Configure ALLOWED_HOSTS
  • Use environment-based configuration (dev/staging/prod)
  • Enable secure cookies and HTTPS settings
Interview Tip: settings.py is loaded once at startup. It configures the entire Django runtime environment. Any misconfiguration here affects the whole application.
7. What is a Model in Django?

A Model in Django represents the data layer of the application. It defines the structure of your database tables using Python classes. Each model class maps directly to a database table, and each attribute inside the model represents a column in that table.

Django uses its built-in ORM (Object-Relational Mapper) to translate these Python classes into SQL statements automatically. This allows developers to interact with the database using Python instead of writing raw SQL queries.

from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)

How This Maps to Database:

  • Post → Table name (usually appname_post)
  • title → VARCHAR(200) column
  • content → TEXT column
  • created_at → DATETIME column

If no primary key is defined, Django automatically adds an id field as an AutoField (integer primary key).

Common Field Types:
  • CharField
  • TextField
  • IntegerField
  • DateTimeField
  • BooleanField
  • ForeignKey
  • ManyToManyField

Model Meta Options:

class Post(models.Model):
    title = models.CharField(max_length=200)
    class Meta:
        ordering = ['-id']
        db_table = 'custom_post_table'

The Meta class allows customization of table name, ordering, verbose names, indexes, and constraints.

Model Lifecycle:

  1. Define model class
  2. Run makemigrations
  3. Run migrate
  4. Django creates/updates database tables

Internally, Django keeps track of model state in migration files and compares changes to generate SQL automatically.

Key Advantages of Django Models:

  • Database abstraction (supports PostgreSQL, MySQL, SQLite, etc.)
  • Built-in validation
  • Relationship handling
  • Query optimization tools
  • Automatic admin integration
Interview Tip: A Django model is not just a table definition - it is a Python abstraction layer over relational databases, managed by Django ORM and migration system.
8. What is ORM in Django?

ORM (Object-Relational Mapping) in Django is a powerful abstraction layer that allows developers to interact with relational databases using Python objects instead of writing raw SQL queries.

Instead of writing SQL like:

INSERT INTO post (title, content) VALUES ('Hello', 'Django ORM');

You write Python code:

Post.objects.create(title="Hello", content="Django ORM")

Django automatically translates this Python code into optimized SQL queries based on the configured database engine (PostgreSQL, MySQL, SQLite, etc.).

How Django ORM Works Internally:

  • Models define database schema.
  • The ORM converts model operations into SQL queries.
  • The database executes SQL.
  • Results are converted back into Python objects.

What is a QuerySet?

A QuerySet is a lazy database lookup object representing a collection of records.

posts = Post.objects.filter(title="Hello")

Lazy Evaluation:

QuerySets are not executed immediately. The SQL query runs only when the data is actually needed (e.g., iterating, converting to list, slicing).

posts = Post.objects.filter(title="Hello") # No query yet
list(posts) # Query executes here
Security Advantage: Django ORM automatically escapes parameters and uses parameterized queries, preventing SQL injection attacks.

Advanced ORM Features:

  • Filtering and chaining queries
  • Aggregation (Count, Sum, Avg)
  • F expressions
  • Q objects for complex conditions
  • select_related() and prefetch_related() for optimization
  • Database indexing support

Query Optimization Example:

Post.objects.select_related("author").all()

This reduces additional database hits when accessing related objects.

Database Abstraction:

Django ORM allows switching databases without changing business logic. Only the database configuration in settings.py needs modification.

Interview Tip: Django ORM is lazy, secure, database-agnostic, and translates Python model operations into optimized SQL queries while maintaining clean and readable code.
9. What are Migrations?

Migrations in Django are version control mechanisms for your database schema. They track changes made to models and translate those changes into SQL operations that modify the database structure.

Whenever you add, remove, or modify fields in a model, Django detects those changes and generates migration files.

python manage.py makemigrations
python manage.py migrate

How Migrations Work:

  1. You modify a model.
  2. makemigrations compares current models with previous migration state.
  3. Django generates a migration file describing the changes.
  4. migrate applies those changes to the database.

What is Inside a Migration File?

class Migration(migrations.Migration):
    dependencies = [ ('blog', '0001_initial'), ]
    operations = [ migrations.AddField( model_name='post', name='published', field=models.BooleanField(default=False), ), ]

A migration file contains:

  • Dependencies – Ensures correct execution order.
  • Operations – Defines schema changes (CreateModel, AddField, RemoveField, AlterField, etc.).
Django stores applied migrations in the django_migrations table inside the database to track which migrations have been executed.

Migration Graph:

Django builds a dependency graph of all migrations across apps. This ensures migrations run in the correct order and prevents schema conflicts.

Common Migration Issues:

  • Merge conflicts when multiple developers create migrations.
  • Missing migrations in version control.
  • Manual database changes causing mismatch.

Advanced Commands:

  • showmigrations – Displays migration status.
  • sqlmigrate app_name migration_number – Shows raw SQL.
  • migrate app_name zero – Rolls back migrations.

Important Concept:

Migrations track model state, not actual database state. Django compares the current model definition with the last recorded migration state to generate new migrations.

Interview Tip: Migrations are Django’s schema versioning system. They allow safe, incremental database evolution across teams and environments.
10. What is a View in Django?

A View in Django is a Python function or class responsible for handling HTTP requests and returning HTTP responses. It acts as the business logic layer of the application and determines what data is processed and what response is returned to the client.

When a user sends a request:

  1. The URL dispatcher maps the request to a specific view.
  2. The view processes the request (interacts with models if needed).
  3. The view returns an HTTP response (HTML, JSON, redirect, file, etc.).
from django.http import HttpResponse
def home(request):
    return HttpResponse("Hello Django")

Types of Views in Django:

1. Function-Based Views (FBV)

Simple Python functions that accept a request object and return a response.

from django.shortcuts import render
def home(request):
    return render(request, "home.html")

2. Class-Based Views (CBV)

Object-oriented approach that allows reusable and structured view logic.

from django.views import View
from django.http import HttpResponse
class HomeView(View):
    def get(self, request):
        return HttpResponse("Hello from CBV")
Class-Based Views provide built-in generic views like ListView, DetailView, CreateView, UpdateView, and DeleteView to speed up development.

The Request Object:

The request parameter contains all information about the incoming HTTP request:

  • request.method – GET, POST, PUT, DELETE
  • request.GET – Query parameters
  • request.POST – Form data
  • request.user – Authenticated user
  • request.session – Session data
  • request.headers – HTTP headers

Common Response Types:

  • HttpResponse
  • JsonResponse
  • Redirect
  • FileResponse
  • TemplateResponse

View Execution Flow Internally:

  • Request passes through middleware.
  • URL resolver maps to view.
  • View executes business logic.
  • Response passes back through middleware.
  • Server sends response to client.
Interview Tip: In Django, views are the core of request handling. They receive the request object, interact with models, and return an HTTP response. Class-Based Views provide more structure and reusability compared to Function-Based Views.
11. What is a Template?

A Template in Django defines the presentation layer of the application. It determines how data is displayed to users using HTML combined with the Django Template Language (DTL).

Templates allow dynamic content to be inserted into HTML files while keeping business logic separate from presentation logic.
{{ post.title }}

In this example, {{ post.title }} is a template variable that gets replaced with actual data passed from the view.

How Template Rendering Works:

  1. A view prepares data (context dictionary).
  2. The view calls render(request, template_name, context).
  3. Django loads the template file.
  4. The template engine processes variables and tags.
  5. Final HTML is returned as an HTTP response.
from django.shortcuts import render
def home(request):
    return render(request, "home.html", {"post": post})

Key Features of Django Template Language (DTL):

  • Variables: {{ variable }}
  • Tags: {% if %}{% for %}{% block %}
  • Filters: {{ name|upper }}
  • Comments: {# This is a comment #}

Template Inheritance (Very Important):

{% block content %}{% endblock %}
{% extends "base.html" %} {% block content %}
Home Page
{% endblock %}

Template inheritance promotes reusable layouts and avoids duplication.

Security Feature: Django templates automatically escape HTML to prevent Cross-Site Scripting (XSS) attacks unless explicitly marked safe.

Template Loaders:

Django searches for templates in directories defined in the TEMPLATES setting (DIRS and APP_DIRS). It loads templates either from project-level directories or inside individual apps.

Separation of Concerns:

Templates should not contain business logic. Heavy processing must be done in views, keeping templates clean and focused only on presentation.

Interview Tip: Django Templates are intentionally limited in logic to enforce separation of concerns and improve security. Complex logic belongs in views or custom template tags.
12. What is urls.py?

urls.py is responsible for routing incoming HTTP requests to the appropriate view functions or class-based views. It acts as the URL dispatcher of a Django project.

When a user visits a URL:

  1. The request first goes to the project's root urls.py.
  2. Django matches the URL pattern.
  3. The mapped view function/class is executed.
  4. The view returns an HTTP response.
from django.urls import path
from . import views
urlpatterns = [ path('', views.home, name="home"), ]

path() vs re_path()

  • path() – Simple and readable URL patterns.
  • re_path() – Uses regular expressions for complex URL matching.
from django.urls import re_path
re_path(r'^post/(?P\d+)/$', views.post_detail)

Dynamic URL Parameters:

path('post//', views.post_detail, name="post_detail")

Including App URLs (Modular Structure):

# project urls.py
from django.urls import path, include
urlpatterns = [ path('blog/', include('blog.urls')), ]

This keeps applications decoupled and scalable.

Named URLs (Very Important):

path('', views.home, name="home")

Using names allows reverse URL resolution:

Or inside views:

from django.urls import reverse
reverse("home")

URL Namespacing:

Used when multiple apps have similar URL names.

app_name = "blog"
path('', views.home, name="home")

Usage:

{% url 'blog:home' %}

URL Resolution Flow Internally:

  • Request enters Django through WSGI/ASGI.
  • Middleware processes the request.
  • URL resolver matches the pattern.
  • Corresponding view executes.
  • Response returns through middleware.
Clean, semantic URLs improve SEO, readability, and maintainability. Always use named URLs instead of hardcoding paths.
Interview Tip: Django follows the "URL-first" design philosophy. URL patterns are explicit and mapped manually, giving full control over routing behavior.
13. What is the Django Admin Panel?

The Django Admin Panel is a built-in, auto-generated interface that allows developers and administrators to manage database records without writing custom CRUD views.

It is powered by the Django ORM and automatically creates forms and dashboards based on registered models.

from django.contrib import admin
from .models import Post
admin.site.register(Post)

After creating a superuser:

python manage.py createsuperuser

The admin panel becomes accessible at /admin.

How Admin Works Internally:

  • Reads model metadata.
  • Generates ModelForm dynamically.
  • Uses Django ORM for database operations.
  • Applies authentication and permission checks.

Customizing Admin with ModelAdmin:

from django.contrib import admin
from .models import Post
class PostAdmin(admin.ModelAdmin):
    list_display = ("title", "author", "created_at")
    search_fields = ("title",)
    list_filter = ("created_at",)
    admin.site.register(Post, PostAdmin)

Important Customization Options:

  • list_display – Columns shown in list view
  • search_fields – Search bar functionality
  • list_filter – Sidebar filters
  • readonly_fields – Prevent field editing
  • ordering – Default sorting

Inline Models (Editing Related Models Together):

class CommentInline(admin.TabularInline):
    model = Comment
    class PostAdmin(admin.ModelAdmin):
        inlines = [CommentInline]

Permissions & Security:

  • Only authenticated staff users can access admin.
  • Supports model-level permissions (add, change, delete, view).
  • Groups can be used to manage role-based access.

When NOT to Use Django Admin:

  • For complex custom workflows.
  • For public-facing dashboards.
  • When heavy UI customization is required.
Django Admin is ideal for internal tools, CMS dashboards, data management systems, and MVP development.
Interview Tip: Django Admin is not just a UI - it dynamically generates CRUD interfaces using model metadata and ModelForms. It leverages Django’s authentication and permission system for security.
14. How do you create a Superuser?

Superuser in Django is a user account that has full administrative access to the project. Superusers can log in to the Admin Panel and manage all models without restrictions.

To create a superuser, run the following command inside your Django project directory:
python manage.py createsuperuser
After running the command, Django will ask for:

  • Username
  • Email address (optional unless configured as required)
  • Password

Once created, you can access the Django Admin Panel at:

http://127.0.0.1:8000/admin/

What Happens Internally?

  • Django creates a record in the auth_user table.
  • The password is securely hashed (not stored as plain text).
  • The fields is_superuser and is_staff are set to True.

Important Notes:

  • You must run python manage.py migrate before creating a superuser.
  • Superusers automatically get all permissions (add, change, delete, view).
  • Do not share superuser credentials in production.
Beginner Tip: A superuser is simply a user with maximum privileges. It is mainly used to manage your application through the Admin Panel.
15. What is Middleware?

Middleware in Django is a framework of hooks that processes requests and responses globally before they reach the view or before they are returned to the client.

It acts like a layer between the web server and the view, allowing you to modify requests and responses.

Simple Flow:

  1. Client sends request
  2. Request passes through Middleware
  3. View processes request
  4. Response passes back through Middleware
  5. Response is sent to client

Common Uses of Middleware:

  • Authentication
  • Session management
  • Security (CSRF protection)
  • Logging
  • Performance monitoring
  • Custom headers

Example: Creating Custom Middleware

class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Code before view runs
        print("Before View")

        response = self.get_response(request)

        # Code after view runs
        print("After View")

        return response



Then register it inside settings.py:

MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'yourapp.middleware.SimpleMiddleware', ]

Built-in Middleware Examples:

  • SecurityMiddleware
  • SessionMiddleware
  • AuthenticationMiddleware
  • CsrfViewMiddleware

How It Works Internally:

  • Middleware is executed in order (top to bottom).
  • Request flows down the list.
  • Response flows upward (reverse order).
  • Each middleware can modify request or response.
Interview Tip: Middleware is executed before and after the view. It forms a request-response processing pipeline and is defined in the MIDDLEWARE setting.
16. What are Static Files?

Static files are files that do not change dynamically. These include:

  • CSS files
  • JavaScript files
  • Images
  • Fonts

They are used to design and add interactivity to the frontend of a Django application.

Basic Configuration in settings.py:

STATIC_URL = '/static/'

Recommended Project Structure:

myproject/

├── static/
        ├── css/
        ├── js/
        └── images/
 

Using Static Files in Templates:

{% load static %}

Development vs Production:

  • Development: Django automatically serves static files when DEBUG=True.
  • Production: You must collect all static files into one folder using:
python manage.py collectstatic

This gathers static files from all apps into the directory defined by:

STATIC_ROOT = BASE_DIR / "staticfiles"

In production, a web server like Nginx or Apache serves static files directly for better performance.

Important Settings:

  • STATIC_URL - URL prefix for static files
  • STATICFILES_DIRS - Additional static directories
  • STATIC_ROOT - Folder where collectstatic stores files
Always use {% static %} template tag instead of hardcoding file paths.
Interview Tip: Static files are served by Django only during development. In production, they are served by a web server after running collectstatic.
17. What are Forms in Django?

Forms in Django are used to handle user input, validate data, and process form submissions securely.

Django provides a built-in Form API that simplifies:

  • Creating HTML forms
  • Validating user input
  • Displaying error messages
  • Protecting against security threats (like CSRF)

Example: Creating a Basic Form

from django import forms
class ContactForm(forms.Form):
    name = forms.CharField(max_length=100)
    email = forms.EmailField()
    message = forms.CharField(widget=forms.Textarea)

Using the Form in a View:

from django.shortcuts import render
from .forms import ContactForm
def contact_view(request):
    if request.method == "POST":
            form = ContactForm(request.POST)
            if form.is_valid():
                # Access cleaned data
                name = form.cleaned_data["name"]
                return render(request, "success.html")
            else:
                form = ContactForm()
                return render(request, "contact.html", {"form": form})

Rendering Form in Template:

{% csrf_token %} {{ form.as_p }} 

How Validation Works:

  • form.is_valid() triggers validation.
  • Built-in field validation runs automatically.
  • Cleaned data is available in form.cleaned_data.
  • Errors are stored in form.errors.

Types of Forms in Django:

  • forms.Form – Manual form (not linked to model)
  • forms.ModelForm – Automatically creates form from a model

Example of ModelForm:

from django.forms import ModelForm
from .models import Post
class PostForm(ModelForm):
    class Meta:
        model = Post
        fields = ["title", "content"]

Security Feature:

Django automatically protects forms against CSRF attacks using {% csrf_token %}.

Interview Tip: Django Forms handle validation on the server side. ModelForms are tightly integrated with the ORM and reduce boilerplate code.
18. What is CSRF Protection?

CSRF (Cross-Site Request Forgery) is a security attack where a malicious website tricks a logged-in user into performing unwanted actions on another website.

Django provides built-in protection against CSRF attacks using a secure token system.

How CSRF Attack Works:

  • User logs into a trusted website.
  • Session cookie is stored in the browser.
  • User visits a malicious site.
  • The malicious site sends a hidden POST request to the trusted site.
  • Since cookies are automatically sent, the request may succeed without protection.

How Django Prevents This:

  • Django generates a unique CSRF token for each session.
  • The token must be included in every POST request.
  • Django verifies the token before processing the request.

Using CSRF Token in Templates:

{% csrf_token %}  

If the token is missing or invalid, Django returns a 403 Forbidden error.

Where CSRF Protection Is Enabled:

  • Handled by CsrfViewMiddleware
  • Enabled by default in the MIDDLEWARE setting

Important Notes:

  • Required only for unsafe methods (POST, PUT, DELETE).
  • Not required for safe methods like GET.
  • Can be disabled for specific views using @csrf_exempt (not recommended unless necessary).
Interview Tip: CSRF protection works by verifying a secret token submitted with POST requests. It ensures that the request originates from the trusted site, not a malicious third party.
19. What is a QuerySet?

QuerySet in Django is a collection of database queries used to retrieve, filter, and manipulate data from the database using Django’s ORM (Object-Relational Mapping).

It represents a list of objects from the database.

Basic Example:

Post.objects.filter(title="Hello")

This returns a QuerySet containing all Post objects where the title is "Hello".

Common QuerySet Operations:

# Get all records
Post.objects.all()
# Filter records
Post.objects.filter(author="Admin")
# Exclude records
Post.objects.exclude(status="draft")
# Get single object
Post.objects.get(id=1)

Important Concept: QuerySets Are Lazy

Django does NOT hit the database immediately when you write a query. The query is executed only when the data is actually needed.

Example:

posts = Post.objects.filter(status="published")
# No database hit yet
for post in posts:
    # Database query happens here
    print(post.title)

When Does QuerySet Execute?

  • When iterating over it
  • When converting to list()
  • When using len()
  • When slicing
  • When printing in shell

QuerySet Chaining:

Post.objects.filter(status="published").order_by("-created_at")

Each filter returns a new QuerySet. They are chainable.

QuerySet vs get():

  • filter() → Returns QuerySet (multiple results)
  • get() → Returns single object (throws error if not found)

Internally:

  • QuerySet converts Python code into SQL queries.
  • It interacts with the database through Django ORM.
  • It caches results after first evaluation.
Interview Tip: QuerySets are lazy, chainable, and represent database queries. The actual SQL query is executed only when the data is evaluated.
20. What is the difference between get() and filter()?

Both get() and filter() are QuerySet methods used to retrieve data from the database, but they behave differently.

1. get()

  • Returns exactly one object.
  • Raises an exception if no object is found.
  • Raises an exception if multiple objects are found.
post = Post.objects.get(id=1)

Possible Exceptions:

  • Post.DoesNotExist
  • Post.MultipleObjectsReturned

2. filter()

  • Returns a QuerySet (a collection of objects).
  • Never raises an error if no results are found.
  • Can return zero, one, or multiple records.
posts = Post.objects.filter(author="Admin")

If no records match, it returns an empty QuerySet instead of raising an error.

Key Differences:

  • Return Type: get() → Single object | filter() → QuerySet
  • Error Handling: get() raises errors | filter() does not
  • Use Case: get() when exactly one result is expected

Example Comparison:

# Using get()
post = Post.objects.get(slug="django-intro")
# Using filter()
posts = Post.objects.filter(slug="django-intro")

Internally:

  • Both generate SQL queries using Django ORM.
  • get() adds a LIMIT clause and checks result count.
  • filter() returns a lazy QuerySet.

Best Practice:

  • Use get() when querying by unique fields (like id, slug, email).
  • Use filter() when multiple results are possible.
Interview Tip: get() is strict and expects exactly one record. filter() is flexible and always returns a QuerySet, even if empty.
21. What is ForeignKey?

ForeignKey in Django creates a many-to-one relationship between two models.

This means multiple records in one model can be associated with a single record in another model.

Example:

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    content = models.TextField()

Here:

  • Many Comment objects can belong to one Post.
  • A foreign key column is created in the Comment table.

on_delete Options (Very Important):

  • CASCADE – Deletes related objects automatically.
  • SET_NULL – Sets value to NULL (requires null=True).
  • PROTECT – Prevents deletion.
  • SET_DEFAULT – Sets default value.
  • DO_NOTHING – No action (may cause DB error).

Accessing Related Objects:

# Get post from comment
comment.post
# Get all comments of a post
post.comment_set.all()

Internally:

  • Django creates a foreign key column in the database.
  • It enforces referential integrity.
  • SQL JOIN is used when querying related data.
Interview Tip: ForeignKey creates a many-to-one relationship and stores the related object's ID in the database.
22. What is ManyToManyField?

ManyToManyField creates a many-to-many relationship between two models.

This means multiple records in one model can relate to multiple records in another model.

Example:

class Course(models.Model):
    name = models.CharField(max_length=100)
    class Student(models.Model):
        name = models.CharField(max_length=100)
        courses = models.ManyToManyField(Course)

Here:

  • One student can enroll in multiple courses.
  • One course can have multiple students.

How It Works Internally:

  • Django automatically creates an intermediate (junction) table.
  • This table stores student_id and course_id pairs.
  • SQL JOIN queries are used to fetch related records.

Adding & Accessing Data:

student = Student.objects.get(id=1)
course = Course.objects.get(id=2)
student.courses.add(course)
student.courses.all()

Custom Through Model (Advanced):

You can define a custom intermediate table using through= if you need extra fields.

class Enrollment(models.Model):
    student = models.ForeignKey(Student, on_delete=models.CASCADE)
    course = models.ForeignKey(Course, on_delete=models.CASCADE)
    enrolled_on = models.DateField()
Interview Tip: ManyToManyField creates an extra join table automatically unless a custom "through" model is defined.
23. What is DEBUG Mode?

DEBUG is a Django setting that controls whether detailed error messages are displayed.

DEBUG = True

When DEBUG = True:

  • Detailed error pages are shown.
  • Full stack trace is displayed.
  • SQL queries may be visible.
  • Static files are served automatically.

This is useful during development but dangerous in production.

When DEBUG = False:

  • Users see a generic error page (500 error).
  • Sensitive information is hidden.
  • You must configure ALLOWED_HOSTS.
DEBUG = False ALLOWED_HOSTS = ["yourdomain.com"]

Why Never Enable DEBUG in Production?

  • Exposes secret keys and environment details.
  • Reveals database structure.
  • Creates major security risks.
Interview Tip: DEBUG=True is only for development. In production, always set DEBUG=False and configure proper logging.
24. How do you deploy Django?

Deploying a Django application involves running it on a production server with proper configuration.

Basic Production Stack:

  • Gunicorn or uWSGI → Application server
  • Nginx → Web server (serves static files & reverse proxy)
  • PostgreSQL/MySQL → Production database
  • Cloud Provider: AWS, DigitalOcean, Azure

Basic Deployment Steps:

  1. Set DEBUG = False
  2. Configure ALLOWED_HOSTS
  3. Set up production database
  4. Run python manage.py collectstatic
  5. Use Gunicorn to run app
  6. Configure Nginx as reverse proxy

Example Gunicorn Command:

gunicorn projectname.wsgi:application

WSGI vs ASGI:

  • WSGI → For synchronous applications
  • ASGI → For async features (WebSockets, real-time apps)

Common Hosting Platforms:

  • AWS EC2
  • DigitalOcean
  • Heroku
  • Render
Interview Tip: Django is not deployed directly with runserver. It must run behind a production-grade server like Gunicorn with Nginx handling static files.
25. Why Choose Django?

Django is a high-level Python web framework designed for rapid development and clean, pragmatic design.

Key Advantages:

  • Built-in Admin Panel
  • Powerful ORM
  • Strong security features (CSRF, XSS, SQL injection protection)
  • Scalable architecture
  • Reusable apps system
  • Large ecosystem and community

Security Built-In:

  • Password hashing
  • CSRF protection
  • Clickjacking protection
  • SQL injection prevention

Best Use Cases:

  • Startups and MVPs
  • Enterprise applications
  • SaaS platforms
  • Content-heavy websites
  • REST APIs (with Django REST Framework)

Why Companies Choose Django:

  • Faster time-to-market
  • Clean MVC-style architecture (MVT pattern)
  • Reduces boilerplate code
  • Easy scaling with caching and database optimization
Django allows developers to focus on business logic instead of reinventing authentication, admin systems, and security features.
Interview Tip: Django follows the “batteries-included” philosophy - most essential tools are built-in, which speeds up development and improves security.

© 2026 Notes Lover. All rights reserved.

Back to top