Skip to main content

Python & Django Interview Questions

Master these 31 carefully curated interview questions to ace your next Python & Django Interview Questions interview.

Quick Answer

Django is a Python web framework following the MVT (Model-View-Template) pattern for rapid, secure web development.

Detailed Explanation

Django's MVT: Model (database layer, ORM), View (business logic, handles requests), Template (presentation layer, HTML). Unlike MVC, Django's View is the controller. Key features: built-in admin, ORM, authentication, URL routing, template engine, middleware, and security features (CSRF, XSS, SQL injection protection). 'Batteries included' philosophy means most web features are built-in.

Quick Answer

Django's ORM maps Python classes to database tables, allowing you to query databases using Python code instead of SQL.

Detailed Explanation

Models define schema: class User(models.Model). Field types: CharField, IntegerField, ForeignKey, ManyToManyField. QuerySet API: User.objects.filter(age__gte=18).order_by('name'). Supports: chaining, aggregation, annotation, F expressions (database-level operations), Q objects (complex queries). Migrations auto-generate from model changes. Supports PostgreSQL, MySQL, SQLite, Oracle. Raw SQL available when needed: User.objects.raw('SELECT ...').

Quick Answer

Migrations are auto-generated Python files that track and apply database schema changes based on model definitions.

Detailed Explanation

Workflow: (1) Modify models.py. (2) python manage.py makemigrations — generates migration file. (3) python manage.py migrate — applies to database. Migrations are version-controlled. Support: creating/dropping tables, adding/removing columns, data migrations (RunPython). Squash migrations to consolidate. Commands: showmigrations (list), sqlmigrate (show SQL), migrate --fake (mark without running). Always test migrations in staging before production.

Quick Answer

FBVs are simple functions handling requests; CBVs use classes with built-in methods for common CRUD patterns.

Detailed Explanation

FBVs: def my_view(request): return HttpResponse('Hello'). Simple, explicit, good for unique logic. CBVs: class MyView(View): def get(self, request): ... — provide mixins (LoginRequiredMixin, CreateView, ListView) for DRY code. Generic CBVs handle CRUD automatically. FBVs are easier to understand; CBVs reduce boilerplate for standard operations. Choose FBVs for custom logic, CBVs for standard CRUD. DRF uses CBVs extensively (APIView, ViewSet).

Quick Answer

Django uses urlpatterns in urls.py to map URL patterns to view functions/classes using path() or re_path().

Detailed Explanation

urls.py: urlpatterns = [path('articles/<int:id>/', views.article_detail)]. Path converters: <int:>, <str:>, <slug:>, <uuid:>. Include app URLs: path('api/', include('myapp.urls')). Named URLs: path('home/', views.home, name='home'). Reverse URL: reverse('home'). Namespace: app_name = 'blog'. URL resolution is top-down — first match wins. Django 2.0+ uses path() (simplified), re_path() for regex patterns.

Quick Answer

Django provides built-in protection against CSRF, XSS, SQL injection, clickjacking, and includes secure authentication.

Detailed Explanation

Security features: (1) CSRF: middleware adds token to forms, validates on POST. (2) XSS: template auto-escaping ({{ variable }} is escaped). (3) SQL Injection: ORM parameterizes queries. (4) Clickjacking: X-Frame-Options middleware. (5) Password storage: PBKDF2 hashing with salt. (6) HTTPS: SECURE_SSL_REDIRECT, SECURE_HSTS_SECONDS. (7) Content-type sniffing protection. (8) Session security: SESSION_COOKIE_HTTPONLY, SESSION_COOKIE_SECURE. Always run python manage.py check --deploy before deploying.

Quick Answer

DRF is a toolkit for building Web APIs in Django with serializers, viewsets, authentication, and browsable API.

Detailed Explanation

Key components: (1) Serializers: convert models to JSON and validate input (ModelSerializer). (2) ViewSets: combine list/create/retrieve/update/delete in one class. (3) Routers: auto-generate URL patterns. (4) Authentication: Token, Session, JWT (via simplejwt). (5) Permissions: IsAuthenticated, IsAdminUser, custom. (6) Pagination: PageNumber, LimitOffset, Cursor. (7) Filtering: django-filter integration. (8) Throttling: rate limiting. (9) Browsable API for easy testing. Most popular choice for Django APIs.

Quick Answer

Middleware is a framework of hooks that process requests/responses globally, running before views and after responses.

Detailed Explanation

Middleware chain: Request → SecurityMiddleware → SessionMiddleware → AuthenticationMiddleware → View → Response (reverse order). Custom middleware: class MyMiddleware: def __init__(self, get_response): ... def __call__(self, request): ... response = self.get_response(request) ... return response. Built-in: CSRF, session, auth, GZip, locale. Use for: logging, request timing, modifying headers, IP blocking, custom auth. Order in MIDDLEWARE setting matters — security first.

Quick Answer

Use select_related, prefetch_related, values/only, indexing, and avoid N+1 queries.

Detailed Explanation

Techniques: (1) select_related(): JOIN for FK/OneToOne (single query). (2) prefetch_related(): separate query for M2M/reverse FK. (3) .only()/.defer(): load specific fields. (4) .values()/.values_list(): return dicts/tuples instead of objects. (5) Database indexes on filtered/ordered fields. (6) django-debug-toolbar to see queries. (7) Bulk operations: bulk_create, bulk_update. (8) Avoid queryset evaluation in loops. (9) Use .count()/.exists() instead of len()/bool(). (10) Raw SQL for complex queries.

Quick Answer

Django supports per-site, per-view, and template fragment caching with backends like Redis, Memcached, and database.

Detailed Explanation

Backends: Redis (django-redis), Memcached, database, file-based, local memory. Levels: (1) Per-site: CacheMiddleware caches entire site. (2) Per-view: @cache_page(60*15) decorator. (3) Template fragment: {% cache 500 sidebar %}. (4) Low-level: cache.set('key', value, timeout). Cache key versioning, cache invalidation strategies. Use Vary header for user-specific caching. Django's cache framework is configurable — switch backends without code changes.

Quick Answer

Django 3.1+ supports async views with async def, ASGI servers (Daphne/Uvicorn), and async ORM operations in Django 4.1+.

Detailed Explanation

async def my_view(request): data = await async_operation(). Deploy with ASGI server: uvicorn project.asgi:application. Django 4.1 added async ORM: await Model.objects.aget(). Async support: views, middleware, tests. Still sync: some ORM operations, template rendering. Use sync_to_async() wrapper for sync-only code. Channels library for WebSockets. Benefits: handle more concurrent connections for I/O-heavy endpoints. Mix sync and async views in same project.

Quick Answer

Django uses transaction.atomic() for database transactions, ensuring all operations succeed or all are rolled back.

Detailed Explanation

Usage: with transaction.atomic(): ... or @transaction.atomic decorator. Django auto-commits each query by default. ATOMIC_REQUESTS setting wraps each view in a transaction. Savepoints: nested atomic() blocks create savepoints. transaction.on_commit() runs code after successful commit (send emails, clear cache). select_for_update() locks rows for concurrent access. DatabaseError/IntegrityError trigger automatic rollback. Always handle TransactionManagementError for operations outside atomic blocks.

Quick Answer

Signals allow decoupled components to notify each other of events like model save, delete, or request start/finish.

Detailed Explanation

Built-in: pre_save, post_save, pre_delete, post_delete, m2m_changed, request_started, request_finished. Usage: @receiver(post_save, sender=User) def create_profile(sender, instance, created, **kwargs). Register in apps.py ready() method. Use for: creating related objects, sending notifications, updating caches, logging. Avoid for: complex business logic (hard to debug), cascading signals. Alternatives: override model.save(), use service layer functions. Signals add implicit coupling — use judiciously.

Quick Answer

Use django-debug-toolbar to find N+1 queries, add caching (Redis), optimize ORM queries, and add database indexes.

Detailed Explanation

Steps: (1) Install django-debug-toolbar — check SQL queries per page (target < 10). (2) Fix N+1 queries with select_related/prefetch_related. (3) Add database indexes on frequently filtered/ordered columns. (4) Implement Redis caching for expensive queries. (5) Use pagination for large querysets. (6) Profile with django-silk or cProfile. (7) Consider read replicas for heavy read loads. (8) CDN for static/media files. (9) Async views for I/O-bound endpoints. (10) Database connection pooling (django-db-connection-pool).

Quick Answer

Use Gunicorn/Uvicorn as WSGI/ASGI server, Nginx as reverse proxy, PostgreSQL, Redis for caching, and Docker for containerization.

Detailed Explanation

Production checklist: (1) DEBUG=False, ALLOWED_HOSTS set. (2) Gunicorn/Uvicorn workers (2*CPU+1). (3) Nginx reverse proxy: serve static files, SSL termination, load balancing. (4) PostgreSQL with connection pooling (pgBouncer). (5) Redis for cache and sessions. (6) Celery for background tasks. (7) Static files: python manage.py collectstatic + whitenoise or CDN. (8) Environment variables for secrets. (9) CI/CD pipeline with tests. (10) Monitoring: Sentry for errors, Prometheus/Grafana for metrics. (11) docker-compose for orchestration.

Quick Answer

Instagram runs the largest Django deployment, using extensive caching, sharding, and custom optimizations to handle billions of users.

Detailed Explanation

Instagram's architecture: (1) Django serves the web tier. (2) PostgreSQL with horizontal sharding. (3) Memcached/Redis for aggressive caching. (4) Cassandra for feed storage. (5) RabbitMQ for async task processing (Celery). (6) Custom Django middleware and optimizations. (7) They contribute back to Django (e.g., async support). Key lesson: Django scales if you optimize queries, cache aggressively, and offload heavy work. They handle millions of requests per second with Python/Django.

Quick Answer

Use Django REST Framework for the API layer, with a machine learning model served via a separate service and cached in Redis.

Detailed Explanation

Architecture: (1) DRF endpoint: /api/recommendations/{user_id}/. (2) ML model trained offline (collaborative filtering, content-based). (3) Model predictions cached in Redis with TTL. (4) Fallback to popular items if cache miss. (5) A/B testing different algorithms. (6) Track user interactions (clicks, skips) for model training. (7) Celery periodic tasks retrain models. (8) Serializer formats response with track metadata. (9) Pagination for recommendation lists. (10) Rate limiting per user.

Quick Answer

Use a counter-based ID encoded to Base62 for short URLs, with Redis caching and PostgreSQL for persistence.

Detailed Explanation

Implementation: (1) Model: ShortURL(original_url, short_code, created_at, click_count). (2) Generate short_code: counter → base62 encode (a-z, A-Z, 0-9). (3) POST /api/shorten — create entry, return short URL. (4) GET /{code} — lookup and redirect (301/302). (5) Redis cache for hot URLs. (6) Analytics: track clicks, referrers, geography. (7) Custom domain support. (8) URL validation and sanitization. (9) Rate limiting on creation. (10) Expiration policy for old URLs. Scale: partition by code prefix.

Quick Answer

select_related uses SQL JOIN for ForeignKey/OneToOne; prefetch_related uses separate queries for ManyToMany/reverse FK.

Detailed Explanation

select_related: single query with JOIN — ideal for ForeignKey and OneToOneField. Reduces N+1 queries. prefetch_related: executes separate query per relation, joins in Python — ideal for ManyToManyField and reverse ForeignKey. select_related('author') generates LEFT JOIN. prefetch_related('tags') runs 2 queries: one for objects, one for all related tags. Use Prefetch object for complex filtering. Django Debug Toolbar helps identify N+1 query problems. Always profile with assertNumQueries in tests.

Quick Answer

Decorators are functions that modify or extend other functions without changing their source code, using the @decorator syntax.

Detailed Explanation

A decorator takes a function, wraps it with additional logic, and returns the wrapper. @decorator is syntactic sugar for func = decorator(func). Common patterns: @login_required (access control), @cache (memoization), @staticmethod, @property. Decorators with arguments: need a decorator factory (function returning a decorator). Use functools.wraps to preserve original function metadata. Class-based decorators use __call__. Django examples: @csrf_exempt, @require_http_methods, @transaction.atomic.

Quick Answer

Generators use yield to produce values lazily one at a time, saving memory compared to building entire lists.

Detailed Explanation

Functions with yield become generators — they pause execution and resume on next(). Memory efficient: process one item at a time instead of loading all into memory. Generator expressions: (x*2 for x in range(1000000)). Use cases: large file processing, infinite sequences, data pipelines, streaming responses in Django. send() sends values into generators. yield from delegates to sub-generators. asyncio uses generators internally. StopIteration signals completion.

Quick Answer

Django wraps each request in a transaction by default, with atomic() decorator for explicit transaction control.

Detailed Explanation

ATOMIC_REQUESTS=True wraps entire view in transaction — rolls back on exception. transaction.atomic() creates savepoints for nested blocks. on_commit() runs callbacks after successful commit (send emails, trigger Celery tasks). select_for_update() locks rows for UPDATE. Isolation levels configurable per database. Common pitfall: code inside atomic() that has side effects (API calls, file writes) still executes even if transaction rolls back — use on_commit(). Durable=True prevents nesting.

Quick Answer

The GIL (Global Interpreter Lock) allows only one thread to execute Python bytecode at a time, limiting CPU-bound parallelism.

Detailed Explanation

The GIL prevents multiple threads from executing Python code simultaneously in CPython. Impact: CPU-bound tasks don't benefit from threading. Solutions: multiprocessing (separate processes, each with own GIL), C extensions (release GIL during computation), asyncio for I/O-bound work. I/O-bound tasks (network, file) release GIL while waiting — threading works fine. Django: use Celery for CPU-intensive tasks, asyncio views for I/O. Python 3.12 introduced sub-interpreters; 3.13 has free-threaded mode (no-GIL experimental).

Quick Answer

Middleware processes requests/responses globally through a chain of components, each wrapping the next in order.

Detailed Explanation

Request flows through MIDDLEWARE list top-to-bottom, response flows bottom-to-top. Each middleware can: process request before view (authentication, CSRF), process response after view (add headers, compress), handle exceptions. Methods: __init__ (one-time setup), __call__ (called per request). process_view() runs after URL resolution. process_exception() handles unhandled exceptions. process_template_response() modifies template responses. Order matters: SecurityMiddleware first, SessionMiddleware before AuthenticationMiddleware. Custom middleware for logging, rate limiting, request ID tracking.

Quick Answer

Profile queries with Django Debug Toolbar, add database indexes, use caching, optimize ORM queries, and add pagination.

Detailed Explanation

Steps: (1) Django Debug Toolbar — identify slow queries and N+1 problems. (2) ORM: select_related/prefetch_related, only/defer, values/values_list. (3) Database indexes: db_index=True, Meta.indexes. (4) Caching: per-view cache, template fragment cache, Redis/Memcached for sessions. (5) Pagination for large querysets. (6) Database connection pooling (pgbouncer). (7) Async views for I/O-bound endpoints. (8) Static file serving via CDN. (9) Celery for background tasks. (10) Monitor with django-silk or New Relic.

Quick Answer

Use Django REST Framework with JWT or Token authentication, serializers for validation, and viewsets for CRUD.

Detailed Explanation

Setup: (1) Install djangorestframework, djangorestframework-simplejwt. (2) Define serializers (ModelSerializer for auto-fields). (3) Create viewsets (ModelViewSet for full CRUD). (4) Register with router for URL generation. (5) JWT auth: obtain token pair on login, access token in Authorization header. (6) Permission classes: IsAuthenticated, IsAdminUser, custom permissions. (7) Throttling: AnonRateThrottle, UserRateThrottle. (8) Pagination: PageNumberPagination. (9) Filtering: django-filter integration. (10) API documentation: drf-spectacular for OpenAPI.

Quick Answer

Use RunSQL for complex operations, create migrations in small steps, test on staging, and use zero-downtime techniques.

Detailed Explanation

Strategies: (1) Small, focused migrations — one change per migration. (2) AddField with null=True first, then data migration, then alter to not null. (3) RunSQL for raw SQL when ORM is too slow. (4) SeparateDatabaseAndState for renaming without data movement. (5) Zero-downtime: never remove columns in same deploy as code — deploy code first, then migrate. (6) django-pg-zero-downtime-migrations for PostgreSQL. (7) Test on staging with production-size data. Instagram uses Django at massive scale with custom sharding.

Quick Answer

Context managers use with statement for resource management, ensuring cleanup via __enter__ and __exit__ methods.

Detailed Explanation

Protocol: __enter__() runs on entering with block, __exit__(exc_type, exc_val, exc_tb) runs on exit (even with exceptions). Common: open() for files, threading.Lock(), database connections. contextlib: @contextmanager decorator simplifies creation using yield. contextlib.suppress() ignores specific exceptions. ExitStack manages multiple context managers dynamically. Django: transaction.atomic() is a context manager. Use for: file handling, locks, database sessions, temporary state changes, timing blocks.

Quick Answer

Django async views use async def and await for non-blocking I/O operations like external API calls and database queries.

Detailed Explanation

Django 3.1+ supports async def views that run in asyncio event loop. Use for: external API calls (aiohttp), WebSocket handling (channels), multiple concurrent I/O operations. async for with ORM (Django 4.1+): async for obj in Model.objects.all(). ASGI deployment required (uvicorn, daphne). Limitations: ORM is sync by default (use sync_to_async wrapper or async ORM methods). Don't use for CPU-bound work. Mix sync and async views in same project. Channels for WebSocket, long-polling, server-sent events.

Quick Answer

Use TestCase for database tests, SimpleTestCase for non-DB, fixtures or factory_boy for data, and test views, models, and forms.

Detailed Explanation

Django TestCase wraps each test in transaction (auto-rollback). Use setUp()/setUpTestData() for test data. factory_boy > fixtures for flexible test data. Test layers: Unit (models, utils), Integration (views, forms), E2E (Selenium/Playwright). Client() simulates requests: self.client.get('/api/'). assertContains, assertRedirects, assertTemplateUsed. Mock external services with unittest.mock. Coverage: coverage.py with --branch. Performance: --parallel flag, in-memory SQLite for speed. CI: run tests before every merge. Django's test runner auto-discovers test*.py files.

Ready to master Python & Django Interview Questions?

Start learning with our comprehensive course and practice these questions.