Interview Questions

Q1. What is Django?


Answer: Django is a high-level Python web framework designed for rapid development. It follows the MVT (Model-View-Template) pattern and includes built-in features like an ORM, authentication, an admin panel, middleware, routing, and security protections.


Interview Tip: Say: “Django is a 'batteries-included' framework—most common web features are available out of the box.”


Q2. What is the MVT architecture in Django?


Answer: MVT stands for:

  • Model: Handles database and data logic.

  • View: Handles business logic and processes requests.

  • Template: Handles UI and presentation layers.


Django internally manages the controller layer through its URL routing system.

Interview Tip: Say: “MVT is Django’s version of MVC, where Django itself acts as the controller.”


Q3. How do you create a new Django project?


Answer: Execute the following terminal commands:

django-admin startproject projectname
cd projectname
python manage.py startapp appname


  • Project: The overall container and configuration for your entire website.

  • App: A specific, isolated module or feature within the project.


Interview Tip: Remember: Project = House, App = Room.


Q4. What is manage.py?


Answer: manage.py is Django’s command-line utility used for managing your project. Common use cases include:

  • Running the development server (python manage.py runserver)

  • Creating and applying database migrations

  • Creating superusers

  • Running test suites and opening the Django interactive shell


# ==========================
# Project & App Management
# ==========================

python manage.py startapp app_name                    # Create a new Django app
python manage.py check                               # Check project configuration for issues
python manage.py check --deploy                      # Check if project is production-ready

# ==========================
# Development Server
# ==========================

python manage.py runserver                           # Start the development server
python manage.py runserver 8080                      # Run server on port 8080
python manage.py runserver 0.0.0.0:8000              # Allow access from other devices on the network

# ==========================
# Database Migrations
# ==========================

python manage.py makemigrations                      # Create migration files from model changes
python manage.py makemigrations app_name             # Create migrations for a specific app
python manage.py migrate                             # Apply all pending migrations
python manage.py migrate app_name                    # Apply migrations for one app
python manage.py migrate app_name 0002               # Migrate to a specific migration version
python manage.py showmigrations                      # Show migration status
python manage.py sqlmigrate app_name 0001            # Display SQL for a migration without executing it

# ==========================
# User Management
# ==========================

python manage.py createsuperuser                     # Create an admin (superuser)
python manage.py changepassword username             # Change a user's password

# ==========================
# Django Shell
# ==========================

python manage.py shell                               # Open the Django interactive shell

# ==========================
# Static Files
# ==========================

python manage.py collectstatic                       # Collect static files into STATIC_ROOT
python manage.py findstatic filename                 # Find the location of a static file

# ==========================
# Testing
# ==========================

python manage.py test                                # Run all tests
python manage.py test app_name                       # Run tests for one app
python manage.py test app_name.tests                 # Run a specific test module
python manage.py test app_name.tests.TestClass       # Run a specific test class
python manage.py test app_name.tests.TestClass.test_method  # Run a single test method

# ==========================
# Database Utilities
# ==========================

python manage.py inspectdb                           # Generate models from an existing database
python manage.py dbshell                             # Open the database command-line shell
python manage.py flush                               # Delete all data but keep the schema
python manage.py dumpdata                            # Export database data as JSON
python manage.py dumpdata app_name                   # Export data for one app
python manage.py dumpdata app_name.ModelName         # Export data for one model
python manage.py loaddata data.json                  # Import data from a fixture

# ==========================
# Cache & Sessions
# ==========================

python manage.py createcachetable                    # Create database cache table
python manage.py clearsessions                       # Delete expired sessions

# ==========================
# Internationalization (i18n)
# ==========================

python manage.py makemessages -l fr                  # Extract translation strings
python manage.py compilemessages                     # Compile translation files

# ==========================
# Email
# ==========================

python manage.py sendtestemail                       # Send a test email using configured email backend

# ==========================
# Help
# ==========================

python manage.py help                                # List all available commands
python manage.py help migrate                        # Show help for the migrate command

# ==========================
# Common Options
# ==========================

python manage.py <command> --verbosity=2             # Increase command output detail
python manage.py <command> --traceback               # Show full traceback on errors
python manage.py <command> --noinput                 # Run without interactive prompts
python manage.py <command> --settings=myproject.settings  # Use a different settings module


ex:python manage.py migrate --verbosity=2

Interview Tip: Say: “manage.py is the primary interface for interacting with and managing a Django project.”


Q5. What is settings.py in Django?


Answer: 

settings.py is the central configuration file of a Django project. It acts as the project's control panel, containing all the global settings required for the application to run. It defines the installed applications (INSTALLED_APPS), database configuration (DATABASES), middleware (MIDDLEWARE), URL configuration (ROOT_URLCONF), template settings (TEMPLATES), security settings such as SECRET_KEY, DEBUG, and ALLOWED_HOSTS, static and media file locations (STATIC_URL, MEDIA_URL),


internationalization settings (LANGUAGE_CODE, TIME_ZONE), and many other project-wide configurations. When the Django server starts, it loads settings.py to configure the entire project. Any change made to this file affects the whole application, making it one of the most important files in every Django project.


# settings.py (Example)

from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = "django-insecure-xxxxxxxxxxxxxxxx"

#secret key is used for session security, csrf protection, password reset tokens,
signed cookies
DEBUG = True
ALLOWED_HOSTS = ["localhost", "127.0.0.1"] INSTALLED_APPS = [     "django.contrib.admin",     "django.contrib.auth",     "django.contrib.contenttypes",     "django.contrib.sessions",     "django.contrib.messages",     "django.contrib.staticfiles",     "positions_board", ] MIDDLEWARE = [     "django.middleware.security.SecurityMiddleware",     "django.contrib.sessions.middleware.SessionMiddleware",     "django.middleware.common.CommonMiddleware",     "django.middleware.csrf.CsrfViewMiddleware",     "django.contrib.auth.middleware.AuthenticationMiddleware",     "django.contrib.messages.middleware.MessageMiddleware", ] ROOT_URLCONF = "core_gate.urls" DATABASES = {     "default": {         "ENGINE": "django.db.backends.postgresql",         "NAME": "company_db",         "USER": "postgres",         "PASSWORD": "password",         "HOST": "localhost",         "PORT": "5432",     } } TEMPLATES = [     {         "BACKEND": "django.template.backends.django.DjangoTemplates",         "DIRS": [BASE_DIR / "templates"],         "APP_DIRS": True,     }, ] WSGI_APPLICATION = "core_gate.wsgi.application"

#The application object is an instance of Django's WSGIHandler class created by get_wsgi_application().

It represents the fully initialized Django application and acts as the entry point

for WSGI servers like Gunicorn or uWSGI. It loads the project's settings,

installed apps, middleware, URL configuration, and other components,

then receives HTTP requests from the web server, routes them through Django, and

returns the generated HTTP responses.

LANGUAGE_CODE = "en-us" TIME_ZONE = "Asia/Kolkata" USE_I18N = True USE_TZ = True

APP_DIRS = True
STATIC_URL = "static/" STATIC_ROOT = BASE_DIR / "staticfiles" MEDIA_URL = "/media/" MEDIA_ROOT = BASE_DIR / "media" DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

Interview Tip:
Mention that production secrets should always be loaded from environment variables rather than hardcoded here.


Q6. What is WSGI and ASGI in Django?


Answer:


WSGI (Web Server Gateway Interface) is the standard interface that allows a web server to communicate with a Django application in a synchronous (blocking) manner. It is used for traditional web applications that follow the request-response model, where each request is processed one at a time by a worker. Django's wsgi.py file contains the WSGI application object, which is loaded by WSGI-compatible servers such as Gunicorn, uWSGI, or Apache with mod_wsgi to serve the application in production.


ASGI (Asynchronous Server Gateway Interface) is the modern successor to WSGI that supports both synchronous and asynchronous (non-blocking) communication. It enables Django to handle multiple concurrent connections efficiently and supports advanced features such as WebSockets, real-time chat, live notifications, streaming, and async views. Django's asgi.py file contains the ASGI application object, which is used by ASGI-compatible servers such as Uvicorn, Daphne, or Hypercorn to deploy applications requiring asynchronous capabilities.


uvicorn my_project.asgi:application
gunicorn my_project.wsgi:application



Interview Tip: Explicitly state that you would use ASGI for real-time applications like chat engines, notification systems, or live dashboards.


Q7. Difference between Django Project and App?

Answer:

FeatureDjango ProjectDjango App
ScopeThe entire website configurationA specific feature or functionality
FilesContains settings.py and root urls.pyContains business logic, models, and views
CompositionCan contain many appsBuilt to be small and reusable across projects

Q8. How does URL routing work in Django?


Answer: URLs are mapped to specific views using the urls.py configuration file.

from django.urls import path

from . import views

urlpatterns = [
    path('', views.home_view, name='home'),
    path('login/', views.login_view, name='login'),
    path('register/', views.register_view, name='register'),
    path('logout/', views.logout_view, name='logout'),
    path('admin-home/', views.admin_home, name='admin_home'),
]


Interview Tip: Emphasize that you always use named URLs (name='home') to allow clean reverse URL matching in templates and views.


Q9. What is Django ORM?


Answer: The ORM (Object-Relational Mapper) allows you to interact with your SQL database using Python classes and object-oriented syntax instead of writing raw SQL queries.

from django.db import models, transaction
from django.db.models import (
    Q, F, Count, Sum, Avg, Max, Min,
    Value, Case, When, IntegerField,
    ExpressionWrapper, OuterRef, Subquery, Exists
)

# Example Model
class Employee(models.Model):
    name = models.CharField(max_length=100)
    department = models.CharField(max_length=100)
    salary = models.DecimalField(max_digits=10, decimal_places=2)
    age = models.IntegerField()
    is_active = models.BooleanField(default=True)

# ==========================================================
# RETRIEVE DATA
# ==========================================================

Employee.objects.all()                                  # Get all employees
Employee.objects.get(id=1)                              # Get employee with id=1
Employee.objects.filter(department="IT")                # Employees in IT
Employee.objects.exclude(is_active=False)               # Exclude inactive employees
Employee.objects.first()                                # First employee
Employee.objects.last()                                 # Last employee
Employee.objects.latest("id")                           # Latest employee by id
Employee.objects.earliest("id")                         # Earliest employee
Employee.objects.none()                                 # Empty queryset

# ==========================================================
# CREATE
# ==========================================================

Employee.objects.create(
    name="Rahul",
    department="IT",
    salary=50000,
    age=25
)                                                       # Create and save

emp = Employee(
    name="Priya",
    department="HR",
    salary=45000,
    age=24
)
emp.save()                                              # Save object

Employee.objects.bulk_create([
    Employee(name="John", department="IT", salary=60000, age=28),
    Employee(name="Alice", department="HR", salary=55000, age=30),
])                                                      # Bulk insert

Employee.objects.get_or_create(
    name="David",
    defaults={
        "department": "Sales",
        "salary": 40000,
        "age": 26
    }
)                                                       # Get or create

Employee.objects.update_or_create(
    name="Rahul",
    defaults={
        "salary": 70000
    }
)                                                       # Update or create

# ==========================================================
# UPDATE
# ==========================================================

Employee.objects.filter(department="IT").update(
    salary=60000
)                                                       # Update multiple rows

emp = Employee.objects.get(id=1)
emp.salary = 65000
emp.save()                                              # Update one row

Employee.objects.bulk_update(
    [emp],
    ["salary"]
)                                                       # Bulk update

Employee.objects.update(
    salary=F("salary") + 5000
)                                                       # Increment salary

# ==========================================================
# DELETE
# ==========================================================

emp.delete()                                            # Delete one employee
Employee.objects.filter(age__lt=18).delete()            # Delete multiple

# ==========================================================
# ORDERING
# ==========================================================

Employee.objects.order_by("salary")                     # Ascending
Employee.objects.order_by("-salary")                    # Descending
Employee.objects.order_by("salary").reverse()           # Reverse order #both same result

# ==========================================================
# COUNT & EXISTS
# ==========================================================

Employee.objects.count()                                # Count employees
Employee.objects.filter(name="Rahul").exists()          # Check if Rahul exists

# ==========================================================
# AGGREGATION
# ==========================================================

Employee.objects.aggregate(
    total=Sum("salary")
)

Employee.objects.aggregate(
    average=Avg("salary")
)

Employee.objects.aggregate(
    maximum=Max("salary")
)

Employee.objects.aggregate(
    minimum=Min("salary")
)

Employee.objects.aggregate(
    total=Count("id")
)

Employee.objects.values("department").annotate(
    total=Count("id")
)                                                       # Count employees by department

# ==========================================================
# VALUES
# ==========================================================

Employee.objects.values("name", "salary")               # Dictionary output

Employee.objects.values_list("name", "salary")          # Tuple output

Employee.objects.only("name")                           # Load only name

Employee.objects.defer("salary")                        # Skip salary initially

# ==========================================================
# DISTINCT
# ==========================================================

Employee.objects.values("department").distinct()        # Unique departments

# ==========================================================
# RELATIONSHIPS
# ==========================================================

# Employee.objects.select_related("manager")            # ForeignKey JOIN
# Employee.objects.prefetch_related("projects")         # ManyToMany optimization

# ==========================================================
# QUERY EXPRESSIONS
# ==========================================================

Employee.objects.filter(
    Q(department="IT") | Q(department="HR")
)                                                       # OR query

Employee.objects.filter(
    Q(age__gt=25) & Q(is_active=True)
)                                                       # AND query

Employee.objects.annotate(
    bonus=ExpressionWrapper(
        F("salary") * 0.10,
        output_field=models.DecimalField()
    )
)                                                       # Calculate 10% bonus

Employee.objects.annotate(
    grade=Case(
        When(salary__gte=70000, then=Value("A")),
        When(salary__gte=50000, then=Value("B")),
        default=Value("C")
    )
)                                                       # Conditional values

# ==========================================================
# SUBQUERY
# ==========================================================

highest_salary = Employee.objects.order_by("-salary").values("salary")[:1]

Employee.objects.filter(
    salary=Subquery(highest_salary)
)                                                       # Employee with highest salary

# ==========================================================
# EXISTS SUBQUERY
# ==========================================================

Employee.objects.annotate(
    has_same_department=Exists(
        Employee.objects.filter(
            department=OuterRef("department")
        ).exclude(id=OuterRef("id"))
    )
)

# ==========================================================
# TRANSACTIONS
# ==========================================================

with transaction.atomic():
    Employee.objects.create(
        name="Tom",
        department="IT",
        salary=80000,
        age=29
    )

# ==========================================================
# MODEL METHODS
# ==========================================================

emp = Employee.objects.get(id=1)

emp.save()                                              # Save changes
emp.delete()                                            # Delete employee
emp.full_clean()                                        # Validate model
emp.refresh_from_db()                                   # Reload from database

# ==========================================================
# RAW SQL
# ==========================================================

Employee.objects.raw(
    "SELECT * FROM app_employee WHERE salary > %s",
    [50000]
)

# ==========================================================
# QUERYSET EVALUATION
# ==========================================================

list(Employee.objects.all())                            # Convert queryset to list
len(Employee.objects.all())                             # Number of objects
bool(Employee.objects.filter(id=1))                     # True if exists

# ==========================================================
# COMBINING QUERYSETS
# ==========================================================

it = Employee.objects.filter(department="IT")
hr = Employee.objects.filter(department="HR")

it.union(hr)                                            # UNION
it.intersection(hr)                                     # INTERSECTION
it.difference(hr)                                       # DIFFERENCE

LookupMeaningExample
__ltLess than (<)age__lt=30
__lteLess than or equal (<=)age__lte=30
__gtGreater than (>)salary__gt=50000
__gteGreater than or equal (>=)salary__gte=50000
__exactExact match (=)name__exact="Rahul"
__iexactCase-insensitive exact matchname__iexact="rahul"

Interview Tip: Say: “The Django ORM abstracts complex database operations directly into maintainable Python code.”


Q10. How do you run the Django development server?

Answer: Run the following command in your terminal:

Bash
python manage.py runserver
To run on a custom port:
Bash
python manage.py runserver 8080


Interview Tip: Never use the built-in Django development server in production; it is not built to scale safely under real-world loads.

2. Models & Databases


Q11. How do you define a model in Django?

Answer: You inherit from models.Model and define database columns as class attributes:

from django.db import models
from django.core.validators import MinValueValidator
from django.urls import reverse
from django.utils import timezone


class Category(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name


class Product(models.Model):

    # =====================================================
    # Fields
    # =====================================================

    name = models.CharField(max_length=100)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.IntegerField(default=0)
    is_available = models.BooleanField(default=True)

    sku = models.CharField(max_length=20, unique=True)

    manufacture_date = models.DateField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    image = models.ImageField(upload_to="products/", null=True, blank=True)

    rating = models.FloatField(default=0)

    discount = models.DecimalField(
        max_digits=5,
        decimal_places=2,
        default=0,
        validators=[MinValueValidator(0)]
    )

    # =====================================================
    # Relationships
    # =====================================================

    category = models.ForeignKey(
        Category,
        on_delete=models.CASCADE,
        related_name="products"
    )

    # =====================================================
    # String Representation
    # =====================================================

    def __str__(self):
        return self.name

    # =====================================================
    # Instance Methods
    # =====================================================

    def final_price(self):
        return self.price - self.discount

    def is_in_stock(self):
        return self.quantity > 0

    def publish(self):
        self.is_available = True
        self.save()

    def unpublish(self):
        self.is_available = False
        self.save()

    # =====================================================
    # Validation
    # =====================================================

    def clean(self):
        if self.price < 0:
            raise ValueError("Price cannot be negative")

    # =====================================================
    # Override Save
    # =====================================================

    def save(self, *args, **kwargs):
        self.name = self.name.title()
        super().save(*args, **kwargs)

    # =====================================================
    # Override Delete
    # =====================================================

    def delete(self, *args, **kwargs):
        print("Deleting Product...")
        super().delete(*args, **kwargs)

    # =====================================================
    # URL Helper
    # =====================================================

    def get_absolute_url(self):
        return reverse("product_detail", args=[self.pk])

    # =====================================================
    # Model Metadata
    # =====================================================

    class Meta:
        db_table = "products"

        ordering = ["name"]

        verbose_name = "Product"

        verbose_name_plural = "Products"

        indexes = [
            models.Index(fields=["name"]),
            models.Index(fields=["price"]),
        ]

        constraints = [
            models.CheckConstraint(
                condition=models.Q(price__gte=0),
                name="price_positive"
            )
        ]

        permissions = [
            ("can_publish", "Can Publish Product"),
            ("can_discount", "Can Apply Discount"),
        ]


Interview Tip: Always mention that defining the __str__() method is vital for making objects readable in the Django Admin panel and shell.


Q12. What are migrations?


Answer: Migrations act as a version control system for your database schema. They translate changes in your Python models into direct SQL statements.

  • python manage.py makemigrations: Generates the migration files based on model changes.

  • python manage.py migrate: Applies those generated migrations to the database.

Interview Tip: Say: “Migrations are version control for the database schema.”


Q13. Difference between null and blank?

Answer:

Contextnullblank
LevelDatabase levelForm validation level
BehaviorStores an actual NULL value in the DB columnAllows the field to be left empty in forms and admin UI

Q14. Common Django field types


Answer: Django provides a rich set of built-in model fields to match SQL data types:

  • Basic: CharField, TextField, IntegerField, BooleanField, DateTimeField, EmailField

  • Relationships: ForeignKey, ManyToManyField, OneToOneField

  • Files: FileField, ImageField


Q15. What is a ForeignKey?


Answer: It creates a many-to-one relationship between databases (e.g., multiple comments belonging to a single post).

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

Interview Tip: Always be prepared to explain the on_delete behavior to show you understand relational integrity.


Q16. What is a ManyToManyField?


Answer: It establishes a many-to-many relationship (e.g., a student can enroll in multiple courses, and a course can have multiple students). Django automatically manages an intermediary join table behind the scenes.

Python
class Student(models.Model):
    courses = models.ManyToManyField(Course)


Q17. Explain on_delete options


Answer: Determines what happens to dependent child records when a parent record is deleted:

OptionMeaning
CASCADEAutomatically deletes child records when the parent is deleted.
PROTECTBlocks deletion of the parent by raising a ProtectedError.
SET_NULLRetains the child record but sets the foreign key reference to NULL (requires null=True).
SET_DEFAULTSets the foreign key to its predefined default value.
DO_NOTHINGTakes no database action, often leading to integrity errors.

Q18. What is the Meta class?


Answer: An inner class used to configure non-field options for a model, such as ordering, table naming conventions, and verbose labels.

Python
class Meta:
    ordering = ['-created_at'] # Sorts newest items first
    db_table = 'custom_products_table'


Q19. What is a Proxy Model?


Answer: A model used to alter the Python-level behavior of an existing model (e.g., adding custom methods or default ordering) without creating a new table or changing the database schema.

class AdminProduct(Product):
    class Meta:
        proxy = True
        ordering = ['name']


Q20. What is an Abstract Model?


Answer: A base class containing fields you want to inherit across multiple models. Django will not create an individual database table for an abstract model.

Python
class BaseModel(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        abstract = True


3. ORM & Queries


Q21. How do you query all objects?

Answer:

Python
Product.objects.all()


Interview Tip: Explain that Django QuerySets are lazy—they do not hit the database until they are explicitly evaluated (like iterating over them or converting them to a list).


Q22. Difference between filter() and get()?


Answer:

Featurefilter()get()
Return ValueReturns a QuerySet (collection of matches)Returns a single object instance
No Matches FoundReturns an empty QuerySet; no errorRaises a DoesNotExist exception
Multiple MatchesReturns all matches safelyRaises a MultipleObjectsReturned exception

Q23. select_related vs prefetch_related


Answer:

Methodselect_related()prefetch_related()
StrategyUses an SQL JOIN in a single queryRuns separate queries and joins data in Python
Use CaseForeignKey and OneToOneFieldManyToManyField and reverse ForeignKeys

Interview Tip: State that these are the absolute primary tools used to solve performance bottlenecks caused by the N+1 query problem.


Q24. What are Q objects?

Answer: Objects used to build complex, compound database queries using logical operators like AND (&), OR (|), and NOT (~).

Python
from django.db.models import Q

# Finds users whose first or last name contains 'john'
User.objects.filter(Q(first_name__icontains='john') | Q(last_name__icontains='john'))


Q25. What are F expressions?


Answer: Expressions that allow you to reference database field values directly within Python code without having to load the values into web server memory first.

Python
from django.db.models import F

# Increments stock securely at the database level
Product.objects.update(stock=F('stock') + 1)


Interview Tip: Emphasize that F expressions prevent race conditions when multiple database operations occur concurrently.


Q26. How do you perform aggregation?

Answer: Use .aggregate() to calculate scalar values (like averages, sums, or counts) over an entire QuerySet.

Python
from django.db.models import Count

total_products = Product.objects.aggregate(total=Count('id'))
# Returns a dictionary: {'total': 42}


Q27. annotate() vs aggregate()


Answer:


aggregate() and annotate() are Django ORM methods used to perform database calculations such as COUNT, SUM, AVG, MIN, and MAX, but they differ in what they return. aggregate() computes a summary value for the entire QuerySet and returns a single dictionary containing the calculated result. It is used when you need overall statistics, such as the total number of employees or the average salary. annotate(), on the other hand, computes values for each object or each group in a QuerySet and adds the calculated value as an extra field, returning a QuerySet. It is commonly used to count related objects, calculate totals per group, or add computed values to every record.


from django.db.models import Count, Avg

# Example Model
class Employee(models.Model):
    name = models.CharField(max_length=100)
    department = models.CharField(max_length=100)
    salary = models.IntegerField()

# -------------------------
# aggregate()
# Calculates a single summary value for the entire QuerySet
# Returns: Dictionary
# -------------------------

Employee.objects.aggregate(
    average_salary=Avg("salary")
)

# Output:
# {
#     "average_salary": 55000
# }


# -------------------------
# annotate()
# Adds a calculated field to each group/object
# Returns: QuerySet
# -------------------------

Employee.objects.values("department").annotate(
    employee_count=Count("id")
)

# Output:
# [
#     {"department": "HR", "employee_count": 5},
#     {"department": "IT", "employee_count": 10},
#     {"department": "Sales", "employee_count": 3}
# ]



Q28. How do you run raw SQL?


Answer: You can fetch model instances using raw SQL with .raw():

Product.objects.raw("SELECT * FROM my_product_table")
Alternatively, bypass the ORM entirely using a cursor connection: from django.db import connection with connection.cursor() as cursor: cursor.execute("UPDATE custom_table SET status = 'active'")


Q29. values() vs values_list()


Answer:

  • values(): Returns a QuerySet containing dictionaries instead of model instances.

  • values_list(): Returns a QuerySet containing tuples. If you pass flat=True, it returns raw single values directly in a flat list.

Python
# Dictionary format
User.objects.values('id', 'username') 

# Flat list of IDs
User.objects.values_list('id', flat=True)


Q30. How do you order query results?


Answer: Use the .order_by() method. Prefixes with a minus sign (-) sort fields in descending order.

Python
# Newest products first
Product.objects.order_by('-created_at')


4. Views

Q31. What are Function-Based Views (FBVs)?


Answer: Plain Python functions that accept an HttpRequest object as their first argument and return an HttpResponse object.

Python
from django.http import HttpResponse

def home(request):
    return HttpResponse("Welcome Home")


Q32. What are Class-Based Views (CBVs)?


Answer: 


A Class-Based View (CBV) is a view implemented as a Python class instead of a function. Django provides generic class-based views that handle common tasks like listing objects, showing details, creating, updating, and deleting records. They promote code reuse through inheritance, make complex views easier to organize, and allow customization by overriding methods such as get_queryset(), get_context_data(), form_valid(), and dispatch().


# ==========================
# models.py
# ==========================
from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.IntegerField()

    def __str__(self):
        return self.name


# ==========================
# views.py
# ==========================
from django.urls import reverse_lazy
from django.views.generic import (
    ListView,
    DetailView,
    CreateView,
    UpdateView,
    DeleteView
)
from .models import Product


# Display all products
class ProductListView(ListView):
    model = Product
    template_name = "products/product_list.html"
    context_object_name = "products"


# Display single product
class ProductDetailView(DetailView):
    model = Product
    template_name = "products/product_detail.html"
    context_object_name = "product"


# Create product
class ProductCreateView(CreateView):
    model = Product
    fields = ["name", "price", "quantity"]
    template_name = "products/product_form.html"
    success_url = reverse_lazy("product-list")


# Update product
class ProductUpdateView(UpdateView):
    model = Product
    fields = ["name", "price", "quantity"]
    template_name = "products/product_form.html"
    success_url = reverse_lazy("product-list")


# Delete product
class ProductDeleteView(DeleteView):
    model = Product
    template_name = "products/product_confirm_delete.html"
    success_url = reverse_lazy("product-list")


# ==========================
# urls.py
# ==========================
from django.urls import path
from .views import *

urlpatterns = [
    path("", ProductListView.as_view(), name="product-list"),
    path("create/", ProductCreateView.as_view(), name="product-create"),
    path("<int:pk>/", ProductDetailView.as_view(), name="product-detail"),
    path("<int:pk>/update/", ProductUpdateView.as_view(), name="product-update"),
    path("<int:pk>/delete/", ProductDeleteView.as_view(), name="product-delete"),
]


# ==========================
# templates/products/product_list.html
# ==========================
"""
<!DOCTYPE html>
<html>
<body>

<h1>Products</h1>

<a href="{% url 'product-create' %}">Add Product</a>

<hr>

{% for product in products %}

<h3>{{ product.name }}</h3>

<p>Price : {{ product.price }}</p>
<p>Quantity : {{ product.quantity }}</p>

<a href="{% url 'product-detail' product.pk %}">View</a>
<a href="{% url 'product-update' product.pk %}">Edit</a>
<a href="{% url 'product-delete' product.pk %}">Delete</a>

<hr>

{% empty %}

<p>No Products Available</p>

{% endfor %}

</body>
</html>
"""


# ==========================
# templates/products/product_detail.html
# ==========================
"""
<!DOCTYPE html>
<html>
<body>

<h1>{{ product.name }}</h1>

<p>Price : {{ product.price }}</p>
<p>Quantity : {{ product.quantity }}</p>

<a href="{% url 'product-update' product.pk %}">Edit</a>
<a href="{% url 'product-delete' product.pk %}">Delete</a>
<a href="{% url 'product-list' %}">Back</a>

</body>
</html>
"""


# ==========================
# templates/products/product_form.html
# ==========================
"""
<!DOCTYPE html>
<html>
<body>

<h1>Product Form</h1>

<form method="POST">
    {% csrf_token %}

    {{ form.as_p }}

    <button type="submit">Save</button>
</form>

<a href="{% url 'product-list' %}">Cancel</a>

</body>
</html>
"""


# ==========================
# templates/products/product_confirm_delete.html
# ==========================
"""
<!DOCTYPE html>
<html>
<body>

<h2>Are you sure you want to delete "{{ product.name }}"?</h2>

<form method="POST">
    {% csrf_token %}

    <button type="submit">Delete</button>
</form>

<a href="{% url 'product-list' %}">Cancel</a>

</body>
</html>
"""


Q33. FBV vs CBV


Answer:

MetricFunction-Based Views (FBVs)Class-Based Views (CBVs)
ReadabilityVery simple, explicit, and easy to read.Requires understanding class flows.
Code ReusabilityCode reuse is difficult; leads to boilerplate.High reusability using mixins and inheritance.
CRUD ControlUses explicit conditional statements (if request.method == 'POST').Handles HTTP verbs natively via class methods (get(), post()).

Q34. What are Mixins?


Answer: 


Mixins are reusable Python classes that provide additional functionality to another class through multiple inheritance. In Django, mixins are commonly used with Class-Based Views (CBVs) to add behavior such as authentication, authorization, permissions, logging, or custom functionality without duplicating code. A mixin is not intended to be used on its own; instead, it is inherited along with a Django view class to extend its capabilities. Django provides built-in mixins such as LoginRequiredMixin, PermissionRequiredMixin, and UserPassesTestMixin, and developers can also create custom mixins for reusable logic.

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView
from django.http import HttpResponse
from .models import Product

# -----------------------------
# Built-in Mixin Example
# -----------------------------
class ProductListView(LoginRequiredMixin, ListView):
    model = Product
    template_name = "products/product_list.html"
    context_object_name = "products"
    login_url = "/login/"

# If the user is not logged in,
# Django automatically redirects to /login/


# -----------------------------
# Custom Mixin Example
# -----------------------------
class LoggingMixin:

    def dispatch(self, request, *args, **kwargs):
        print(f"{request.user} accessed {request.path}")
        return super().dispatch(request, *args, **kwargs)


class DashboardView(LoggingMixin, LoginRequiredMixin, ListView):
    model = Product
    template_name = "dashboard.html"


# Mixin Order:
# DashboardView
#      │
#      ▼
# LoggingMixin
#      │
#      ▼
# LoginRequiredMixin
#      │
#      ▼
# ListView
#      │
#      ▼
# View


# Common Django Mixins
# --------------------
# LoginRequiredMixin        -> User must be logged in
# PermissionRequiredMixin   -> User must have specific permission
# UserPassesTestMixin       -> Custom authorization check
# SuccessMessageMixin       -> Displays success messages
# ContextMixin              -> Adds extra context to templates


Q35. How do you redirect in Django?


Answer: Use the redirect shortcut utility, passing it a view name, URL path, or model object.

Python
from django.shortcuts import redirect

def legacy_view(request):
    return redirect('home') # Resolves via named URL route


Q36. What is render()?

Answer: A built-in helper function that combines a given template file with a data context dictionary and returns a fully rendered HttpResponse containing the resulting HTML.

Python
from django.shortcuts import render

def home(request):
    return render(request, 'home.html', {'title': 'Homepage'})


Q37. Handling GET and POST requests in FBVs


Answer: You explicitly inspect the request.method attribute:

Python
def contact_view(request):
    if request.method == 'POST':
        # Process the form submission data
        pass
    else:
        # Render a clean, empty form for GET
        pass


Q38. HttpRequest vs HttpResponse


Answer:

  • HttpRequest: The incoming metadata payload generated by the browser (contains query params, headers, cookies, forms, and body data).

  • HttpResponse: The outgoing raw data payload returned by your Django view back to the requesting client browser.


Q39. What is get_object_or_404()?


Answer: A shortcut utility that calls .get() on a model, but automatically raises an HTTP 404 Not Found exception if the targeted record does not exist, keeping your view code clean.

Python
from django.shortcuts import get_object_or_404

product = get_object_or_404(Product, id=product_id)


Q40. What are Generic Views?


Answer: Built-in Class-Based Views designed to handle common web tasks right out of the box without boilerplate code. Examples include:

  • ListView / DetailView: For fetching data arrays or single rows.

  • CreateView / UpdateView / DeleteView: For complete standard CRUD workflows.

5. Templates


Q41. What is Django Template Language (DTL)?


Answer: Django's built-in syntax engine for rendering dynamic text layouts. It relies on specific delimiters:

  • {{ value }}: Outputs computed variable values to the page.

  • {% logic %}: Evaluates control flow loops, structures, and tags.

  • {# comment #}: Internal documentation ignored by rendering pipelines.


Q42. What is Template Inheritance?


Answer: A mechanism allowing you to build a master base skeleton (base.html) containing structural blocks that child templates override as needed.

HTML
<!-- base.html -->
<html>
  <body>
    {% block content %}{% endblock %}
  </body>
</html>

<!-- child.html -->
{% extends 'base.html' %}
{% block content %}
  <h1>This fits inside the base layout!</h1>
{% endblock %}


Q43. What are template filters?


Answer: Pipeline inline modifiers that format or transform variable values immediately prior to display.

HTML
{{ user.name|upper }}
{{ event.date|date:'Y-m-d' }}


Q44. What are template tags?

Answer: Logic tags that control template output using execution operations like loops, URL rendering, or file imports.

HTML
{% if items %}
  {% for item in items %}
    <p>{{ item }}</p>
  {% endfor %}
{% endif %}


Q45. How do you include templates?


Answer: Use the {% include %} tag to modularize common visual assets (like alerts, navigation headers, or footers) cleanly across pages.

HTML
{% include 'partials/navbar.html' %}

Q46. What is template context?


Answer: A dictionary mapping Python variable names directly to data structures, enabling views to pass records securely into template components.

Python
# Passed context dictionary to template target
return render(request, 'home.html', {'username': 'Alex'})

Q47. Handling static files

Answer: Use the {% load static %} tag to point securely to asset files managed by the server storage stack:

HTML
{% load static %}
<link rel="stylesheet" href="{% static 'css/core.css' %}">

Q48. Difference between {{ }} and {% %}

Answer:

  • {{ }}: Evaluation tool used strictly to output text or variables on screen.

  • {% %}: Execution system used to perform structural control logic like loops or template configuration.


Q49. URL reversing in templates


Answer: Uses the {% url %} tag to dynamically fetch path strings via the route's name property, avoiding broken hardcoded endpoints if routes change.

HTML
<a href="{% url 'product-detail' product.id %}">View Product</a>

Q50. What is CSRF?

Answer: Cross-Site Request Forgery is a vulnerability where malicious sites trick users into executing actions on other sites. Django blocks this globally by verifying a unique cryptographic hash included via the {% csrf_token %} tag within form structures.

HTML
<form method="POST">
    {% csrf_token %}
    <button type="submit">Secure Submit</button>
</form>



6. Authentication & Authorization


Q51. Django authentication system

Answer: A robust, built-in framework that handles user accounts, group configurations, cookie sessions, and discrete row-level action permissions natively out of the box.


Q52. How to login/logout programmatically?

Answer: Import Django's helper methods to securely create or destroy active user sessions:

Python
from django.contrib.auth import authenticate, login, logout

# Validate credentials
user = authenticate(username='john', password='secret_password')
if user is not None:
    login(request, user) # Sets up engine session

# Destroy session
logout(request)


Q53. What is @login_required?


Answer: A function decorator that restricts view routing by automatically redirecting unauthenticated visitors to the login portal.

Python
from django.contrib.auth.decorators import login_required

@login_required
def standard_dashboard(request):
    return render(request, 'dashboard.html')


Q54. Custom User model

Answer: Extending AbstractUser to add fields to the user model before running your first database migrations.

Python
from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    phone_number = models.CharField(max_length=15)
Update configuration in settings.py:
Python AUTH_USER_MODEL = 'my_app.CustomUser'


Q55. Permissions and Groups


Answer:

  • Permissions: Granular binary flags mapping to actions (add, change, delete, view) on database rows.

  • Groups: Group collections of permissions (e.g., "Editors", "Moderators") that you apply to users collectively to simplify permissions management.


Q56. Checking permissions

Answer: Use .has_perm() to check permissions on user object models:

Python
if request.user.has_perm('catalog.add_product'):
    # Allow user to add a product
    pass


Q57. Authentication vs Authorization


Answer:

  • Authentication: Confirming identity credentials ("Who are you?").

  • Authorization in Django is the process of determining what an authenticated user is allowed to do. Authentication verifies the identity of a user, whereas authorization determines whether the user has permission to perform specific actions such as creating, viewing, updating, or deleting data. By default, Django does not automatically protect your CRUD views. If you do not add any authorization checks, any user who can access the view can perform the operation. Django provides built-in model permissions (add, change, delete, and view) and also allows developers to define custom permissions. Permissions can be assigned directly to users or, more commonly, through Groups (roles such as Admin, Manager, or Employee). To enforce authorization, Django provides the @permission_required decorator, which automatically checks whether the logged-in user has the required permission before executing the view. Alternatively, developers can manually check permissions using request.user.has_perm() when custom authorization logic is needed. In enterprise applications, Role-Based Access Control (RBAC) using Groups and Permissions is the standard approach for managing user access securely.


from django.contrib.auth.decorators import login_required, permission_required
from django.http import HttpResponse
from django.core.exceptions import PermissionDenied

# Using Django's permission_required decorator
@login_required
@permission_required("shop.add_product", raise_exception=True)
def create_product(request):
    return HttpResponse("Product created successfully.")


# Manual permission check (useful for custom logic)
@login_required
def update_product(request):
    if not request.user.has_perm("shop.change_product"):
        raise PermissionDenied("You do not have permission to update products.")

    return HttpResponse("Product updated successfully.")



Q58. How Django stores passwords

Answer: Django never writes passwords as plain text. It forces one-way cryptographic encryption routines using PBKDF2 algorithms combined with individual unique SHA256 character hashes (salts).


Q59. Social authentication packages

Answer: Production environments integrate external social login strategies using popular packages like:

  • django-allauth

  • social-auth-app-django


Q60. JWT Authentication

Answer: JSON Web Tokens offer standard stateless API user session tracking. Instead of server-side sessions, the client transmits an encrypted token header via standard production extensions like djangorestframework-simplejwt.


7. Django Admin


Q61. What is Django Admin?

Answer: A fully-functional, auto-generated web panel built directly from model declarations, providing internal teams with instant CRUD capabilities to manage application data.


Q62. How do you create a superuser?

Answer: Execute the following terminal command and follow the prompts:

Bash
python manage.py createsuperuser



Q63. Customizing admin


Answer: Register your configuration using an ModelAdmin class:

Python
from django.contrib import admin
from .models import Product

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'price']
    search_fields = ['name']


Q64. What is list_display?


Answer: A configuration property within an admin class specifying which database columns should be rendered as fields in the model summary listing view.


Q65. What are Inline Admins?

Answer: Interface blocks allowing editors to modify related parent-child dependent models inline directly on the same admin detail page. Django provides two visual layouts: TabularInline and StackedInline.

8. Django REST Framework (DRF)


Q66. What is DRF?


Answer: Django REST Framework (DRF) is a powerful toolkit built on top of Django for building RESTful APIs that communicate using JSON instead of HTML. It allows frontend applications like React, Angular, Vue, mobile apps, or other backend services to interact with your Django application through HTTP methods such as GET, POST, PUT, PATCH, and DELETE. DRF provides built-in features such as Serializers for converting Django models to JSON and validating incoming data, APIView, Generic Views, ViewSets, Routers, Authentication (Session, Token, JWT), Permissions, Pagination, Filtering, and Throttling, which reduce boilerplate code and improve security. To use DRF, first install it using pip install djangorestframework, then add 'rest_framework' to the INSTALLED_APPS list in settings.py. In enterprise applications, ModelViewSet is commonly used because it automatically provides complete CRUD operations, making API development faster, cleaner, and more maintainable.

# Install Django REST Framework
pip install djangorestframework

# settings.py
INSTALLED_APPS = [
    ...
    "rest_framework",
]

# models.py
from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)


# serializers.py
from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = "__all__"


# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Product
from .serializers import ProductSerializer

class ProductAPIView(APIView):

    # GET - List all products
    def get(self, request):
        products = Product.objects.all()
        serializer = ProductSerializer(products, many=True)
        return Response(serializer.data)

    # POST - Create a product
    def post(self, request):
        serializer = ProductSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


# urls.py
from django.urls import path
from .views import ProductAPIView

urlpatterns = [
    path("api/products/", ProductAPIView.as_view(), name="products"),
]

# CRUD Endpoints
# GET    /api/products/        -> List all products
# POST   /api/products/        -> Create a product
# (To support Retrieve, Update and Delete, create another APIView
#  with get(id), put(id), patch(id) and delete(id) methods.)



Q67. What is a Serializer?

Answer:

A serializer in DRF acts as a bridge between Django models and JSON data. It serializes model objects into JSON for API responses and deserializes incoming JSON into Python objects, validates the data, and saves it to the database. It eliminates the need for manual JSON conversion and validation, making API development simpler, more secure, and more maintainable.


Q68. APIView vs ViewSet


Answer:

FeatureAPIViewViewSet
Design StyleExplicit HTTP methods (get, post, put, delete).Grouped CRUD actions (list, create, retrieve, update).
BoilerplateHigh control, but requires manual method definitions.Automatically maps routes using Routers, reducing boilerplate.

Q69. What are Routers?


Answer: DRF components that automatically generate the complete set of URL patterns for a ViewSet, eliminating the need to write individual paths manually.

Python
from rest_framework.routers import DefaultRouter
from .views import ProductViewSet

router = DefaultRouter()
router.register(r'products', ProductViewSet)
urlpatterns = router.urls


Q70. DRF Authentication types


Answer: DRF supports multiple built-in authentication strategies out of the box:

  • SessionAuthentication: Uses Django's default browser session cookies.

  • TokenAuthentication: A simple token-based HTTP header authentication system.

  • BasicAuthentication: Standard HTTP Basic authentication (mainly for testing).

  • JWT Authentication: Implemented via third-party libraries like simplejwt.


Q71. DRF Permissions


Answer: DRF Permissions determine whether an authenticated or unauthenticated user is allowed to access a specific API endpoint. While Django's authentication verifies the identity of a user, permissions decide what actions that user can perform on an API. DRF provides several built-in permission classes such as AllowAny, IsAuthenticated, IsAdminUser, IsAuthenticatedOrReadOnly, and DjangoModelPermissions. Permissions can be applied globally in settings.py or at the individual view level using the permission_classes attribute. You can also create custom permission classes by inheriting from BasePermission when business-specific authorization logic is required. In enterprise applications, permissions are commonly combined with JWT authentication and Django Groups to implement secure Role-Based Access Control (RBAC).

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import (
    AllowAny,
    IsAuthenticated,
    IsAdminUser,
    IsAuthenticatedOrReadOnly,
    DjangoModelPermissions
)

# Anyone can access
class PublicAPIView(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        return Response({"message": "Public API"})


# Only authenticated users
class UserAPIView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({"message": "Authenticated User"})


# Only admin users (is_staff=True)
class AdminAPIView(APIView):
    permission_classes = [IsAdminUser]

    def get(self, request):
        return Response({"message": "Admin User"})


# Everyone can read, only authenticated users can modify
class ProductAPIView(APIView):
    permission_classes = [IsAuthenticatedOrReadOnly]

    def get(self, request):
        return Response({"message": "List Products"})

    def post(self, request):
        return Response({"message": "Product Created"})


# Uses Django model permissions (add/change/delete/view)
class ProductPermissionAPIView(APIView):
    permission_classes = [DjangoModelPermissions]
    queryset = Product.objects.all()

    def get(self, request):
        return Response({"message": "Uses Django Model Permissions"})




Q72. What is Throttling?


Answer: A security mechanism used to limit the rate of API requests a user or IP address can make within a given timeframe to prevent abuse or DDoS attacks.

Python
'DEFAULT_THROTTLE_RATES': {
    'user': '1000/day',
    'anon': '100/day'
}


# settings.py

REST_FRAMEWORK = {
    "DEFAULT_THROTTLE_CLASSES": [
        "rest_framework.throttling.AnonRateThrottle",
        "rest_framework.throttling.UserRateThrottle",
    ],
    "DEFAULT_THROTTLE_RATES": {
        "anon": "10/minute",   # Anonymous users
        "user": "100/minute",  # Authenticated users
    },
}

# views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle

class ProductAPIView(APIView):
    throttle_classes = [UserRateThrottle]

    def get(self, request):
        return Response({"message": "Products fetched successfully"})


Q73. What is Pagination?


Answer: The practice of breaking large API datasets into smaller, manageable chunks (pages) to optimize network performance. DRF supports:

  • PageNumberPagination: Standard page-based navigation (?page=2).

  • LimitOffsetPagination: Position-based navigation (?limit=10&offset=20).

  • CursorPagination: High-performance, cryptographically secure cursor navigation optimized for large, real-time datasets.


Q74. ModelSerializer vs Serializer

Answer:

  • ModelSerializer: Automatically discovers fields and validation rules based on a defined Django model, speeding up development.

  • Serializer: A generic, highly flexible base serializer class that requires explicit manual field definitions, ideal for processing non-model data.


Q75. Filtering querysets in DRF

Answer: You can filter API responses using backend components like:

  • DjangoFilterBackend: Filters results based on exact field matches.

  • SearchFilter: Enables full-text search across specified model fields.

  • OrderingFilter: Allows clients to dynamically sort results via query parameters.


9. Advanced Django


Q76. What is Middleware?

Answer: A framework of hooks that execute globally during the Django request/response lifecycle. Middleware components run sequentially to process incoming requests before they reach a view, or modify outgoing responses before they reach the browser.


Q77. Custom Middleware

Answer: A custom middleware can be written as a callable class that wraps the request/response lifecycle:

Python
class PerformanceLoggingMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # 1. Processing logic here BEFORE the view is executed
        response = self.get_response(request)
        # 2. Processing logic here AFTER the view is executed
        return response


Q78. What are Signals?

Answer: A built-in implementation of the Observer pattern that allows decoupled components to receive notifications when specific events occur elsewhere in the application. Common built-in signals include:

  • pre_save / post_save: Triggered immediately before or after a model's .save() method runs.

  • pre_delete / post_delete: Triggered immediately before or after an object is deleted.


Q79. What is Celery?

Answer: An asynchronous task queue used to run resource-intensive operations (like sending transactional emails, generating PDF reports, or processing images) in the background, keeping your main web application fast and responsive.


Q80. Django Caching

Answer: 


Celery is a distributed task queue used to execute background and asynchronous tasks outside the main request-response cycle. Instead of making users wait for time-consuming operations such as sending emails, generating reports, processing images, or importing large files, Django sends these tasks to Celery, which processes them in the background. Celery works with a message broker such as Redis or RabbitMQ to queue tasks and uses workers to execute them. This improves application performance, scalability, and user experience. In enterprise applications, Celery is commonly used for email notifications, scheduled jobs, payment processing, data synchronization, report generation, and other long-running tasks.

# 1. Install
# pip install celery redis

# 2. settings.py
CELERY_BROKER_URL = "redis://localhost:6379/0"
CELERY_RESULT_BACKEND = "redis://localhost:6379/0"

# 3. project/celery.py
import os
from celery import Celery

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

app = Celery("project")
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()

# 4. project/__init__.py
from .celery import app as celery_app

__all__ = ("celery_app",)

# 5. app/tasks.py
from celery import shared_task
import time

@shared_task
def send_email():
    time.sleep(5)
    print("Email sent successfully")

# 6. views.py
from .tasks import send_email

def create_user(request):
    # Save user...
    send_email.delay()   # Runs asynchronously
    return HttpResponse("User created")

# 7. Start Redis
# redis-server

# 8. Start Celery Worker
# celery -A project worker --loglevel=info

# 9. View Logs
# Terminal:
# celery -A project worker --loglevel=info
#
# Save logs to file:
# celery -A project worker --loglevel=info --logfile=celery.log
#
# View log file:
# tail -f celery.log


Q81. ContentTypes Framework

Answer: A built-in framework that tracks all models installed in your project, allowing you to create generic polymorphic relationships where a single model can have a foreign key to any other table.


Q82. File uploads in Django

Answer: Uploaded files are processed by Django's upload handlers and populated into the request.FILES dictionary. To save them safely, handle them through a verified form or map them directly to a model using a FileField or ImageField.


Q83. What is Django Channels?

Answer: An extension that transforms Django from a strictly synchronous framework into an asynchronous powerhouse, adding native support for protocols like WebSockets, MQTT, and chat-based tooling.


Q84. Database Connection Pooling

Answer: Reusing existing database connections instead of opening and closing a new connection for every single request. In Django, this can be configured using the CONN_MAX_AGE setting, or handled via external tools like PgBouncer in high-traffic production environments.


Q85. What is the N+1 Query Problem?

Answer: A common performance bottleneck where an application runs one initial query to fetch a list of parent records, and then executes an additional query for each parent record to fetch its related child data inside a loop.

  • The Fix: Use .select_related() or .prefetch_related() to join and fetch all necessary data upfront in a minimal number of queries.


Q86. What is the Django Shell?

Answer: An interactive Python environment loaded with your project's configuration, settings, and models, making it an excellent tool for testing ORM queries, running scripts, and debugging issues.

Bash
python manage.py shell


Q87. Custom Management Commands

Answer: Custom administrative tasks you can run via manage.py. To create one, define a Python module within a management/commands/ directory inside an active app:

Python
from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = 'Cleans expired user sessions'

    def handle(self, *args, **options):
        # Custom administrative logic goes here
        self.stdout.write(self.style.SUCCESS('Successfully cleaned sessions.'))


Q88. Django Test Framework

Answer: A built-in testing suite based on Python's native unittest library. It includes utilities like a programmatic test client to simulate user requests, inspect status codes, and verify database changes without affecting production data.


Q89. TestCase vs TransactionTestCase

Answer:

  • TestCase: Wraps every test in a database transaction and rolls it back when the test finishes. This is very fast and works well for the vast majority of tests.

  • TransactionTestCase: Resets the database by truncating tables instead of using rollbacks. This is slower but necessary when testing asynchronous code, multi-threaded features, or raw transactional commits.


Q90. Django Production Deployment Stack

Answer: A standard, proven architecture for deploying Django securely at scale includes:

  • WSGI/ASGI Server: Gunicorn or Uvicorn to run the Python process.

  • Reverse Proxy: Nginx or Apache to handle incoming traffic, manage SSL certificates, and serve static assets.

  • Database: A production-grade relational database like PostgreSQL.

  • Caching/Queue Layer: Redis for caching data and managing Celery background tasks.


Q91. What is django-debug-toolbar?

Answer: A widely used development tool that renders a visual sidebar in your browser, providing detailed, real-time insights into execution times, active cache hits, template rendering paths, and raw SQL queries triggered by the page.


Q92. What are Fixtures?

Answer: Data serialized into files (usually JSON or YAML) used to populate a database with initial lookup data or mock test records.

  • python manage.py dumpdata > backup.json: Exports database data to a file.

  • python manage.py loaddata backup.json: Imports data from a fixture file back into the database.


Q93. What is django-environ?

Answer: A popular third-party package used to load configuration settings and production secrets from a .env file into settings.py based on Twelve-Factor App principles.


Q94. Managing Multiple Environments in Django

Answer: Instead of using a single settings.py file, complex projects often break configuration into a modular settings package:

Plaintext
settings/
  ├── __init__.py
  ├── base.py       # Shared configurations
  ├── development.py# Local testing overrides
  └── production.py # Strict security configurations


Q95. What is WhiteNoise?

Answer: A Python package that allows a Django application to serve its own static files directly, eliminating the need for an external web server like Nginx. This is ideal for containerized apps deployed on platforms like Heroku, Railway, or Docker.


Q96. Django Security Checklist

Answer: Essential steps required to secure a Django application before moving it to a live production environment:

  • Set DEBUG = False.

  • Generate a unique, strong SECRET_KEY stored securely outside of your codebase.

  • Configure explicit domain strings in ALLOWED_HOSTS.

  • Enable SECURE_SSL_REDIRECT, SESSION_COOKIE_SECURE, and CSRF_COOKIE_SECURE.

  • Run Django's built-in deployment verification check:

Bash
python manage.py check --deploy


Q97. Sending emails in Django

Answer: Django provides a simple SMTP interface out of the box. To send an email, configure your email backend settings in settings.py and call send_mail:

Python
from django.core.mail import send_mail

send_mail(
    'Subject Line',
    'Body text goes here.',
    '[email protected]',
    ['[email protected]'],
    fail_silently=False,
)


Q98. Session vs Cookie

Answer:

  • Cookie: A small text file stored directly on the user's browser. Because cookies can be inspected or modified by the client, they should not be used to store sensitive data.

  • Session: Data stored securely on the web server. Django sends a single cookie containing an encrypted session ID to the client's browser, which acts as a key to safely look up matching session data on the server.


Q99. What is ORM Lazy Loading?

Answer: A performance feature where a QuerySet compiles the SQL structure but delays executing the query against the database until you explicitly try to use the data (e.g., when iterating over it, slicing it, or casting it to a list).

Python
# No database query is executed here yet
active_users = User.objects.filter(is_active=True)

# The database query is executed here when iteration begins
for user in active_users:
    print(user.username)



Q100. How do you optimize Django performance?

Answer: A production-proven checklist for optimizing performance across Django applications:

  1. Reduce Database Hits: Use .select_related() and .prefetch_related() to avoid N+1 query problems.

  2. Streamline Queries: Use .only() or .defer() to fetch only the database columns you actually need, or use .exists() and .count() instead of loading entire QuerySets into memory.

  3. Implement Caching: Use Redis to cache expensive database queries, complex view layouts, or full API responses.

  4. Offload Heavy Tasks: Move long-running tasks like processing uploads or sending emails out of the request-response cycle and into Celery background queues.

  5. Database Tuning: Add explicit database indexes (db_index=True) to fields that are searched or filtered frequently, and use connection pooling to manage connections efficiently.


Interview Tip: Always emphasize that optimization should be driven by real data—start by profiling your application using tools like django-debug-toolbar to find actual bottlenecks before writing optimization code.

Interview Questions in Django · interview-questions | Django | Careeroza