76 Django Interview Questions and Answers (2026)

Blog / 76 Django Interview Questions and Answers (2026)
Django

Django has quietly become the default for shipping Python APIs and AI/ML backends, which means more companies run it and more interviewers expect real fluency. Knowing the syntax isn't enough anymore — they'll probe how QuerySets evaluate, how the request lifecycle works, and how you'd scale it. Walk in shaky on this and you hand the offer to someone who isn't.

This guide gives you 76 questions with concise, interview-ready answers and code where it actually helps. They're worked Junior to Mid to Senior, so you start with fundamentals and build toward the ORM internals, DRF, async, and security questions that separate hires from maybes. Work through them and you'll have answers ready before the question lands.

Q1.
Django is often called an 'MTV' framework. Explain the difference between Model-Template-View and the traditional Model-View-Controller pattern. Why did Django choose this variation?

Junior

MTV is essentially MVC with renamed components: Django's "View" is the controller logic, and the "Template" is the presentation layer. The framework itself acts as the dispatcher that wires them together.

  • The mapping:

    • Model = Model (data and business rules, the ORM layer).

    • Template = View in MVC (the HTML/presentation).

    • View = Controller in MVC (decides what data to fetch and which template to use).

  • Where the "Controller" went: Django considers the framework itself the controller: URL dispatch routes requests to views automatically.

  • Why Django chose it:

    • Django argues the term "view" should describe what data is presented, not how it looks, so naming follows responsibility rather than convention.

    • It is a naming difference, not an architectural one: separation of concerns is the same goal as MVC.

Q2.
In Django's philosophy, what is the conceptual difference between a 'Project' and an 'App'? When should a feature be its own app versus part of an existing one?

Junior

A project is the entire web application (the configuration and collection of apps), while an app is a self-contained module providing one specific piece of functionality. A feature deserves its own app when it is cohesive and potentially reusable; it belongs in an existing app when it's tightly coupled to that app's domain.

  • Project:

    • The deployable whole: holds settings.py, root URLs, WSGI/ASGI entry points.

    • There is one project; it contains and configures many apps via INSTALLED_APPS.

  • App:

    • A focused module (models, views, templates, migrations) doing one thing well, e.g. blog or payments.

    • Designed to be reusable and pluggable across projects.

  • When to make a new app:

    • The feature has a clear, independent responsibility and its own data models.

    • You might reuse or extract it later.

    • Keep it in an existing app when the feature is just a logical extension of that app's domain: splitting would create artificial coupling.

Q3.
Explain the purpose of the settings.py file and name three critical configurations found there.

Junior

settings.py is the single Python module that configures the entire Django project: it defines how the framework, apps, database, and security behave at runtime.

  • What it does: Centralizes all configuration as Python variables that Django reads via django.conf.settings.

  • Three critical configurations:

    • DATABASES: connection details (engine, name, credentials, host) for the ORM.

    • INSTALLED_APPS: the apps Django loads, enabling models, migrations, admin, and templates.

    • SECRET_KEY: cryptographic signing key for sessions, CSRF tokens, and password reset links: must be kept secret.

  • Other notable ones: DEBUG, ALLOWED_HOSTS, MIDDLEWARE all directly affect security and behavior.

Q4.
What is the role of __init__.py in a Django app directory, and why is it necessary for the framework to recognize it?

Junior

__init__.py marks a directory as a Python package, which is what lets Django (and Python's import system) import the app's modules like models and views. Without it, the folder is just a directory, not an importable module.

  • Primary role: Tells Python "this directory is a package," enabling dotted imports like from blog.models import Post.

  • Why Django needs it: Django imports apps by name from INSTALLED_APPS; the import only resolves if the directory is a package.

  • It can hold code too: Optionally used to set default_app_config (older Django) or run package-level initialization.

  • Nuance: Python 3 supports namespace packages without it, but Django apps conventionally and reliably use an explicit __init__.py.

Q5.
What is the difference between get() and filter() in the ORM, and what exceptions can get() raise?

Junior

get() returns exactly one object and raises if it can't, while filter() returns a (possibly empty) queryset of zero or more matches.

  • get(): a single instance:

    • Raises DoesNotExist if no row matches.

    • Raises MultipleObjectsReturned if more than one matches.

    • Use when you expect exactly one record (e.g. by primary key).

  • filter(): a queryset:

    • Never raises for empty results: returns an empty queryset.

    • Lazy and chainable; use when expecting zero, one, or many.

  • Tip: Use get_object_or_404() in views to turn DoesNotExist into a 404.

Q6.
What is the difference between values() and values_list() in a QuerySet?

Junior

Both return lightweight data instead of model instances: values() yields dictionaries keyed by field name, while values_list() yields tuples of field values.

  • values(): dicts: Each row is {'field': value, ...}; convenient for JSON-like output.

  • values_list(): tuples:

    • Each row is a tuple of values in field order.

    • Pass flat=True with a single field to get a flat list of scalars.

  • Why use them: Skip model instantiation overhead when you only need raw columns.

python

Book.objects.values("id", "title") # [{'id': 1, 'title': 'X'}] Book.objects.values_list("id", "title") # [(1, 'X')] Book.objects.values_list("title", flat=True) # ['X', 'Y']

Q7.
In Django REST Framework (DRF), what is the difference between a Serializer and a ModelSerializer?

Junior

A Serializer is the generic base where you declare every field and write your own create()/update(); a ModelSerializer is a subclass that auto-generates fields and these methods from a model, removing boilerplate.

  • Serializer:

    • You explicitly declare each field and implement create() and update().

    • Best for non-model data, complex shapes, or aggregating multiple sources.

  • ModelSerializer:

    • Infers fields, validators (including unique constraints), and provides default create()/update() from the model.

    • Configured via an inner Meta with model and fields.

  • Rule of thumb: Use ModelSerializer for straightforward model CRUD; drop to Serializer when the payload doesn't map cleanly to one model.

python

class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ["id", "username", "email"]

Q8.
What is the role of a Serializer in DRF, and how does it differ from a Django Form?

Junior

A DRF Serializer converts between complex types (model instances, querysets) and Python primitives for JSON, and validates incoming data; it plays the same validation role as a Django Form but is built for APIs rather than HTML.

  • What a serializer does:

    • Serialization: turns objects into primitive types ready for rendering to JSON.

    • Deserialization + validation: parses incoming data, validates it via is_valid(), and can save it.

  • How it differs from a Django Form:

    • Forms target HTML rendering and form-encoded data; serializers target any content type (JSON, etc.) and bidirectional object conversion.

    • Serializers handle nested/related objects and produce structured output; Forms validate flat input and render widgets.

  • Shared ideas: Both expose is_valid(), cleaned_data/validated_data, and field-level/object-level validation hooks.

Q9.
How does Django's Migration system work, and why do we need both makemigrations and migrate?

Junior

The migration system is Django's way of evolving the database schema in sync with your models, in versioned steps. It is two phases on purpose: makemigrations computes and records the changes as files, and migrate applies those files to the actual database.

  • makemigrations: author the change:

    • Compares the current model state to the last migration's state and emits a new migration file containing operations like AddField or CreateModel.

    • Touches no database; it just produces code you can review and commit to version control.

  • migrate: apply the change:

    • Runs unapplied migrations as SQL against the DB and records them in django_migrations.

    • Idempotent: already-applied migrations are skipped.

  • Why split them:

    • Separation of intent and execution: you generate and review changes on a dev machine, then apply the identical files across staging/production and every teammate's DB.

    • Lets migrations be portable artifacts (committed, diffed, edited as data migrations) rather than one-off live schema edits.

Q10.
Where is the session ID stored in a default Django setup, and how does the server verify it?

Junior

In a default Django setup, the session ID lives in a cookie named sessionid in the browser, while the actual session data is stored server-side in the database. The server verifies a request by looking up that ID.

  • Where it's stored:

    • Client side: a sessionid cookie holding only an opaque random key.

    • Server side: the session payload in the django_session table (default db backend), keyed by that ID.

  • How verification works:

    1. SessionMiddleware reads the sessionid from the incoming cookie.

    2. It looks up the matching row; if found and unexpired, it loads the data into request.session.

    3. AuthenticationMiddleware reads the stored _auth_user_id to set request.user.

  • Other backends exist (cache, signed_cookies); only signed_cookies stores the actual data client-side.

Q11.
Explain the difference between null=True and blank=True in a model field.

Junior

They control validation at two different layers: null=True affects the database (allows NULL in the column), while blank=True affects form/validation (the field may be left empty).

  • null=True is database-level: The column accepts NULL, meaning "no value stored".

  • blank=True is validation-level: Used by forms and the admin; the field can be submitted empty without a "required" error.

  • String fields: avoid both: For CharField/TextField Django convention is to use blank=True only, storing "" rather than NULL to avoid two "empty" states.

  • Common combos: An optional non-string field (e.g. DateField) often uses both null=True, blank=True.

Q12.
What is 'Middleware' in Django, and how does the order of the MIDDLEWARE list affect the application?

Junior

Middleware is a chain of hooks that wrap every request/response, letting you run code before the view sees the request and after it produces a response; because it's a chain, the order in MIDDLEWARE determines what wraps what.

  • What it is:

    • A callable that gets the request, optionally processes it, calls the next layer (eventually the view), then processes the response on the way out.

    • Used for cross-cutting concerns: sessions, authentication, CSRF, security headers, gzip.

  • Order is an onion:

    • On the way in, middleware runs top to bottom; on the way out, bottom to top.

    • A middleware later in the list is wrapped by the ones above it.

  • Why order matters:

    • AuthenticationMiddleware must come after SessionMiddleware because it reads the session.

    • A middleware can short-circuit (return a response early), so anything below it never runs for that request.

Q13.
What is Django Middleware, and how do the process_request and process_response hooks work?

Junior

Middleware is a layer of hooks that wrap request/response processing globally: each middleware sees the request on the way in and the response on the way out, forming an onion around your views.

  • Modern middleware is a callable:

    • Since Django 1.10 it's written as a factory: a callable receiving get_response and returning a function that takes a request.

    • Code before calling get_response() runs on the way in; code after runs on the way out.

  • Legacy hook methods still supported:

    • process_request: runs before URL resolution; returning a response short-circuits the chain.

    • process_response: runs after the view, must return a response object, and runs in reverse order.

  • Ordering matters: Request phase runs top-to-bottom through MIDDLEWARE; response phase unwinds bottom-to-top.

  • Common uses: authentication, sessions, CSRF, GZip, security headers.

python

def timing_middleware(get_response): def middleware(request): # before view (request phase) response = get_response(request) # after view (response phase) return response return middleware

Q14.
What is the Django Admin, and how does it discover which models to display?

Junior

The Django Admin is an auto-generated, model-driven web interface for CRUD operations on your data, intended for trusted staff users. It discovers models through an explicit registration step performed when each app's admin.py is autodiscovered.

  • What it provides: List, add, edit, delete pages plus search, filters, and permissions, all derived from model field definitions.

  • How discovery works:

    • On startup admin.autodiscover() imports the admin.py module of every app in INSTALLED_APPS.

    • Models appear only when explicitly registered with admin.site.register(Model) or the @admin.register decorator.

  • Customization: A ModelAdmin subclass controls list_display, search_fields, list_filter, inlines, and more.

python

from django.contrib import admin from .models import Article @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ("title", "published") search_fields = ("title",)

Q15.
Explain the conceptual difference between STATIC_URL and MEDIA_URL. Why should you never serve these files using the Django application server in production?

Junior

Both are URL prefixes, but they serve different file categories: STATIC_URL is for developer-shipped assets (CSS, JS, images), while MEDIA_URL is for user-uploaded files. Neither should be served by the Django app server in production because that wastes the worker on slow file I/O a web server does far better.

  • STATIC_URL: Files you author and version-control; collectstatic gathers them into STATIC_ROOT for deployment.

  • MEDIA_URL: Runtime user uploads stored under MEDIA_ROOT; unpredictable and untrusted, so often need access control.

  • Why not serve via Django in production:

    • Each file blocks a WSGI/ASGI worker that should be handling dynamic requests.

    • Web servers (Nginx) or a CDN/object store (S3) handle caching, range requests, and concurrency far more efficiently.

    • Django's static() helper only works when DEBUG is on, by design.

Q16.
Why is it a security risk to keep DEBUG = True in a production environment?

Junior

With DEBUG = True, Django exposes detailed error pages and internal behavior intended only for developers; in production this leaks sensitive information and weakens protections, handing attackers a roadmap to your system.

  • Information disclosure:

    • Unhandled exceptions render full tracebacks with source code, local variable values, and the SQL being run.

    • Settings are shown (with some keys masked, but much context exposed), revealing structure attackers can exploit.

  • Weakened host protection: When DEBUG is True, ALLOWED_HOSTS validation is effectively bypassed, enabling Host header attacks.

  • Memory and performance: Django stores every executed query in memory for debugging, which leaks memory over a long-running process.

  • Correct setup: Set DEBUG = False, configure ALLOWED_HOSTS, and provide custom 404/500 templates plus real logging.

Q17.
How does URL routing work in Django, and what is the difference between path() and re_path()?

Junior

Django matches an incoming request's path against an ordered list of URL patterns in urlpatterns, and dispatches to the first view whose pattern matches. path() uses simple readable route syntax with typed converters, while re_path() uses regular expressions for more complex matching.

  • How routing works:

    • Django loads the root URLconf (ROOT_URLCONF), checks patterns top to bottom, and stops at the first match.

    • Captured parts of the URL are passed to the view as arguments; include() lets you delegate to per-app URLconfs.

  • path() uses route converters:

    • Syntax like <int:id> captures and type-casts (int, str, slug, uuid, path).

    • Cleaner and preferred for most routes.

  • re_path() uses regular expressions:

    • Use named groups like (?P<year>[0-9]{4}) for complex patterns path converters can't express.

    • More powerful but harder to read; reach for it only when needed.

python

from django.urls import path, re_path urlpatterns = [ path('articles/<int:year>/', views.year_archive), re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), ]

Q18.
How does Django's template inheritance work, and what is the purpose of the {% block %} and {% extends %} tags?

Junior

Template inheritance lets a child template reuse a parent's structure and override only specific regions. {% extends %} declares the parent, and {% block %} defines named, overridable sections.

  • {% extends %}:

    • Must be the first tag in the child template; it names the base template the child builds on.

    • The child only supplies content for blocks; everything else comes from the parent.

  • {% block %}:

    • Defines a named region in the parent (e.g. {% block content %}) that children can replace.

    • Content inside a block in the parent acts as a default if the child doesn't override it.

  • Overriding and extending:

    • A child overrides a block by redefining it with the same name.

    • Use {{ block.super }} to include the parent's block content instead of fully replacing it.

  • Benefit: a single base layout (header, nav, footer) avoids duplication across pages (DRY).

html

<!-- base.html --> <title>{% block title %}Site{% endblock %}</title> <body>{% block content %}{% endblock %}</body> <!-- page.html --> {% extends "base.html" %} {% block title %}Home{% endblock %} {% block content %}<h1>Welcome</h1>{% endblock %}

Q19.
What is the difference between a Form and a ModelForm in Django?

Junior

A Form is a standalone collection of fields you define manually, while a ModelForm auto-generates its fields from a model and can save validated data directly to the database. Use a ModelForm when the form maps to a model; a plain Form when it doesn't.

  • Form:

    • You declare every field explicitly; not tied to any model.

    • Best for inputs without a database table behind them (search, contact, login, filters).

    • You handle saving/processing the cleaned_data yourself.

  • ModelForm:

    • Builds fields automatically from a model via an inner Meta with model and fields.

    • Provides save() to create or update the model instance, and includes model-level validation.

    • Reduces duplication: field types, max lengths, and constraints come from the model.

  • Shared behavior: Both validate via is_valid() and support clean() / clean_<field>() hooks; ModelForm simply subclasses BaseForm with model wiring.

python

class ArticleForm(forms.ModelForm): class Meta: model = Article fields = ['title', 'body'] form = ArticleForm(request.POST) if form.is_valid(): form.save() # creates/updates the Article

Q20.
Walk me through the lifecycle of a request in Django from the moment it hits the server until a response is returned.

Mid

A request flows through the WSGI/ASGI server into Django's handler, passes down and back up the middleware stack, gets routed by URL resolution to a view, and the view returns a response that travels back out through middleware to the client.

  1. Server entry: The web server (Gunicorn, uWSGI) passes the raw request to Django via WSGIHandler (or ASGIHandler).

  2. Middleware (request phase): Each middleware in MIDDLEWARE runs top to bottom, handling sessions, auth, CSRF, etc. before the view.

  3. URL resolution: The URLconf (ROOT_URLCONF) matches the path against urlpatterns and picks the view, capturing any path kwargs.

  4. View execution: The view runs business logic, queries via the ORM, and returns an HttpResponse (often rendering a template).

  5. Middleware (response phase): The response travels back up through middleware in reverse order (adding headers, cookies, etc.).

  6. Server returns response: Django hands the finished response back to the server, which sends it to the client.

Q21.
Why does Django use a settings.py file for configuration, and what are the trade-offs of using environment variables versus hardcoded settings?

Mid

Django uses a Python settings.py module so configuration is centralized, importable, and expressible with real code. The trade-off is between keeping secrets/per-environment values out of source (env vars) versus the simplicity but danger of hardcoding them.

  • Why a Python module:

    • It's just Python: you can compute paths, branch on environment, and import values.

    • One canonical location accessed through django.conf.settings.

  • Environment variables:

    • Pros: keep secrets out of version control, differ safely per environment (dev/staging/prod), align with twelve-factor practices.

    • Cons: must be set and managed externally, easy to forget, and untyped (everything is a string).

  • Hardcoded settings:

    • Pros: simple, explicit, nothing to configure.

    • Cons: leaks secrets into git, can't vary by environment, dangerous for SECRET_KEY and DEBUG.

  • Common pattern: Read sensitive values via os.environ (or libraries like django-environ), keep non-secret defaults in the file.

Q22.
Explain how Django's QuerySets are 'lazy.' At what exact points is a database query actually executed?

Mid

A QuerySet is lazy: building or chaining it (.filter(), .exclude()) never touches the database. The SQL only runs when you actually consume the results, and the outcome is then cached on the QuerySet.

  • Why laziness helps: You can chain and compose filters cheaply; Django builds one efficient query and defers it until needed.

  • What triggers evaluation:

    • Iteration: a for loop or comprehension over the QuerySet.

    • Slicing with a step, or indexing a single item (e.g. qs[0]).

    • len(), list(), bool() (e.g. if qs:), and repr().

    • Terminal methods like .get(), .count(), .exists(), .first(), .aggregate().

  • Caching:

    • Once evaluated, results are cached on the QuerySet, so re-iterating the same instance won't re-query.

    • A re-derived or re-filtered QuerySet is a new object and will hit the database again.

python

qs = Post.objects.filter(active=True) # no query yet qs = qs.order_by("-created") # still no query for post in qs: # query runs here, results cached print(post.title)

Q23.
What is the difference between select_related and prefetch_related, and when would you use one over the other?

Mid

Both optimize related-object access, but select_related follows single-valued relations with a SQL JOIN, while prefetch_related handles multi-valued relations with a separate query and joins in Python.

  • select_related: SQL JOIN:

    • For ForeignKey and OneToOneField (the "one" side).

    • Pulls related rows in one query via a JOIN, so no extra round trips.

  • prefetch_related: separate query + Python join:

    • For ManyToManyField and reverse FK (the "many" side).

    • Runs a second query and stitches results together in memory.

  • Choosing between them:

    • Single related object: use select_related.

    • Collections of related objects: use prefetch_related.

    • You can chain both in one query for nested relations.

Q24.
Explain the N+1 query problem in the context of the Django ORM. How do select_related and prefetch_related solve this, and what are the technical differences between them?

Mid

The N+1 problem is running 1 query to fetch a list of objects, then 1 extra query per object to load a related record (N more), exploding into N+1 queries. Both select_related and prefetch_related collapse those extra queries.

  • The cause: Django querysets are lazy; accessing obj.related in a loop triggers a fresh query each iteration.

  • select_related fix:

    • Adds a SQL JOIN so related rows arrive with the initial query: 1 query total.

    • Works only for FK/one-to-one relations.

  • prefetch_related fix:

    • Issues 2 queries (one for the base set, one for related objects using an IN clause), then maps them in Python.

    • Works for many-to-many and reverse FK.

  • Technical difference: JOIN vs in-memory join: select_related widens one query, prefetch_related runs additional queries to avoid huge JOIN duplication.

python

# N+1: one query for books, one per author for book in Book.objects.all(): print(book.author.name) # extra query each loop # Fixed: single JOIN for book in Book.objects.select_related("author"): print(book.author.name)

Q25.
Explain the difference between Q and F objects.

Mid

Q objects build complex query conditions (combining filters with AND/OR/NOT), while F objects reference a model field's value inside a query so you can compare or update columns against each other without pulling data into Python.

  • Q: logical composition of conditions:

    • Combine with & (AND), | (OR), ~ (NOT).

    • Needed for OR logic, which plain keyword filters can't express.

  • F: reference field values in the database:

    • Compare two fields, or update a field based on its own value atomically (avoiding race conditions).

    • The arithmetic runs in SQL, not Python.

python

# Q: OR condition Product.objects.filter(Q(price__lt=10) | Q(on_sale=True)) # F: atomic increment in SQL Product.objects.filter(id=1).update(views=F("views") + 1)

Q26.
What is the difference between annotate() and aggregate() in the Django ORM?

Mid

aggregate() computes a single summary value over the whole queryset and returns a dict, while annotate() computes a per-object (or per-group) value and attaches it to each row in the returned queryset.

  • aggregate(): one result for the set:

    • Returns a plain dictionary, e.g. {'price__avg': 42.0}.

    • Terminal: ends the queryset.

  • annotate(): one result per row:

    • Adds a computed attribute to each object; returns a queryset you can keep filtering/ordering.

    • Combined with values() it produces GROUP BY aggregates per group.

python

# aggregate: single value Book.objects.aggregate(Avg("price")) # {'price__avg': 42.0} # annotate: per-object count Author.objects.annotate(num_books=Count("book"))

Q27.
What do defer() and only() do, and when would you use them?

Mid

Both control which fields load from the database to reduce column transfer: only() loads only the named fields, while defer() loads everything except the named fields. Deferred fields are fetched lazily on first access.

  • only(): whitelist: Selects just the listed columns (plus the PK).

  • defer(): blacklist: Loads all columns except the named ones, handy to skip large fields like text or blobs.

  • The catch:

    • Accessing a deferred/excluded field triggers an extra query per object, which can reintroduce N+1 if misused.

    • Worth it only when the skipped columns are large and genuinely unused on that code path.

Q28.
Why is bulk_create() more efficient than saving objects in a loop, and what are its limitations?

Mid

bulk_create() inserts many objects in a small number of SQL statements instead of one INSERT (and round trip) per .save(), drastically cutting database overhead.

  • Why it's faster:

    • Batches rows into one (or few) multi-row INSERT statements, reducing network round trips and query overhead.

    • Honors batch_size to split very large inserts.

  • Limitations:

    • Does not call save() or send pre_save/post_save signals.

    • Primary keys may not be populated on older DBs/backends (PostgreSQL does return them).

    • Doesn't work with multi-table inheritance and can't handle M2M relations.

    • auto_now / custom save() logic is bypassed.

python

Author.objects.bulk_create([ Author(name="A"), Author(name="B"), ], batch_size=500)

Q29.
What is the purpose of database indexes in Django models, and how do you define them?

Mid

Database indexes speed up read queries by letting the DB find rows without scanning the whole table; in Django you define them on fields or via Meta.indexes for composite/named indexes.

  • Why they matter: They make filtering, ordering, and joins on indexed columns much faster, but cost extra storage and slow down writes (each insert/update maintains the index).

  • Field-level indexing:

    • Set db_index=True on a field to create a single-column index.

    • Fields with unique=True or a ForeignKey are indexed automatically.

  • Meta.indexes for composite/conditional indexes: Use models.Index(fields=[...]) for multi-column indexes; you can name them and add condition for partial indexes.

  • Choosing what to index: Index columns used in frequent filter(), order_by(), or join conditions; avoid over-indexing low-selectivity or write-heavy columns.

python

class Order(models.Model): customer = models.ForeignKey(Customer, on_delete=models.CASCADE) # auto-indexed status = models.CharField(max_length=20, db_index=True) created = models.DateTimeField() class Meta: indexes = [ models.Index(fields=["status", "created"], name="status_created_idx"), ]

Q30.
Explain the difference between an APIView and a ViewSet in DRF, and when is the 'magic' of a ViewSet a disadvantage?

Mid

An APIView maps HTTP methods to explicit handler methods on one endpoint, while a ViewSet groups related actions (list, retrieve, create, etc.) into one class that a Router auto-wires into URLs; that automation is a disadvantage when you need fine control over routing or behavior.

  • APIView: You define get(), post(), etc., and wire URLs yourself: explicit and flexible.

  • ViewSet:

    • Defines actions like list()/retrieve(); ModelViewSet provides full CRUD out of the box.

    • A Router generates the URL patterns automatically, minimizing boilerplate.

  • When the magic hurts:

    • Implicit routing makes URLs harder to read; non-standard or custom endpoints fight the convention.

    • Behavior is hidden in mixins, so debugging and customizing edge cases is less obvious than explicit views.

Q31.
Explain the 'Throttling' mechanism in DRF. Why is it important for public-facing APIs?

Mid

Throttling limits how many requests a client can make in a time window, protecting the API from abuse and overload; DRF applies it via throttle classes that return HTTP 429 when limits are exceeded.

  • How DRF implements it:

    • Set DEFAULT_THROTTLE_CLASSES and DEFAULT_THROTTLE_RATES (e.g. "100/hour").

    • Built-ins: AnonRateThrottle (by IP), UserRateThrottle (by user), ScopedRateThrottle (per-view scopes).

  • Why it matters for public APIs:

    • Prevents abuse, brute-force, and scraping, and protects shared resources from a single noisy client.

    • Enables fair usage and tiered plans (different rates per user class).

  • Caveats:

    • It's rate limiting, not security; counters are cache-backed so a shared cache is needed across instances.

    • IP-based throttling is weak behind proxies/NAT: configure trusted proxy headers carefully.

Q32.
Explain the difference between authentication_classes and permission_classes.

Mid

They run in sequence and answer different questions: authentication_classes determines who you are (identifies the request), while permission_classes determines whether that identity is allowed to perform the action.

  • authentication_classes:

    • Inspect credentials (token, session, JWT) and set request.user / request.auth.

    • Failing to authenticate doesn't necessarily reject: it just leaves the user anonymous.

  • permission_classes:

    • Run after authentication and decide access via has_permission() / has_object_permission().

    • Examples: IsAuthenticated, IsAdminUser, or custom object-level rules.

  • Status codes reflect the split: Authentication failure typically yields 401; permission failure yields 403.

Q33.
What are nested serializers, and what performance risks are associated with them?

Mid

Nested serializers embed one serializer inside another to represent related objects inline (e.g. an order with its items); their main risk is the N+1 query problem and heavy payloads when relations aren't fetched efficiently.

  • What they are:

    • A serializer field whose value is another serializer, often with many=True for to-many relations.

    • They produce structured, nested JSON instead of flat IDs.

  • Performance risks:

    • N+1 queries: each parent triggers extra queries for its children unless prefetched.

    • Large response payloads and deep nesting increase serialization cost and over-fetching.

  • Mitigations:

    • Use select_related (FK/one-to-one) and prefetch_related (to-many) on the queryset.

    • Writable nesting needs custom create()/update(); consider PrimaryKeyRelatedField for writes and nested output only for reads.

Q34.
How does pagination work in Django and in Django REST Framework?

Mid

Pagination splits a large result set into pages so you transfer and render only a slice at a time. Plain Django uses the Paginator class (great for templates); DRF offers pluggable pagination classes that build the page and the navigation metadata for API responses.

  • Django core: the Paginator class:

    • Wrap a queryset/list: Paginator(qs, per_page), then paginator.get_page(number) returns a Page object.

    • The Page exposes .object_list, .has_next(), .number, etc.; Django applies a LIMIT/OFFSET slice to the queryset.

  • DRF: pagination classes:

    1. PageNumberPagination: ?page=3, simple page numbers (uses OFFSET under the hood).

    2. LimitOffsetPagination: ?limit=10&offset=40, client controls window size.

    3. CursorPagination: opaque cursor over an ordered field; stable under inserts and avoids deep-OFFSET cost.

  • Configuration:

    • Set globally via DEFAULT_PAGINATION_CLASS and PAGE_SIZE, or per-view with pagination_class.

    • DRF responses include count, next, previous automatically.

  • Performance note: OFFSET-based paging scans and discards skipped rows, so deep pages get slow; prefer CursorPagination (keyset) on large, frequently changing tables.

Q35.
How does Django handle database migrations, and how do you resolve a migration conflict in a team environment?

Mid

Django migrations are versioned Python files that describe schema changes; the framework tracks which have run and applies the rest in dependency order. Conflicts arise when two branches each add a migration with the same parent, creating two leaf nodes for one app.

  • How migrations track state:

    • Each migration declares dependencies, forming a directed graph; applied ones are recorded in the django_migrations table.

    • makemigrations reads model changes and writes new migration files; migrate executes the unapplied ones against the DB.

  • Why team conflicts happen: Two developers branch from 0004 and each create 0005_*; after merge the app has two leaves and Django refuses to migrate ("conflicting migrations").

  • How to resolve:

    1. Run python manage.py makemigrations --merge: Django generates a merge migration depending on both leaves, re-linearizing the graph.

    2. If the two migrations changed the same field incompatibly, talk to the team, possibly delete one branch's migration and regenerate it on top of the other.

    3. Review the merge migration and test against a fresh DB before committing.

  • Prevention: Rebase before generating migrations, keep migrations small, and never edit a migration that teammates have already applied.

Q36.
How does Django handle database transactions? Explain the difference between transaction.atomic and transaction.on_commit.

Mid

Django runs each query in autocommit by default, but you group statements into a single all-or-nothing unit with transaction.atomic. transaction.on_commit is different: it registers a callback that fires only after the surrounding transaction successfully commits, so it's for side effects that must not run if the transaction rolls back.

  • transaction.atomic: atomic block:

    • Used as a decorator or context manager; on success it commits, on any exception it rolls back the whole block.

    • Nesting creates savepoints, so an inner block can roll back without aborting the outer one.

  • transaction.on_commit: post-commit hook:

    • Schedules a function to run once the data is truly durable; if the transaction rolls back, the callback never runs.

    • Solves a classic bug: firing a Celery task or sending an email inside atomic can reference rows that don't exist yet if the worker reads before commit.

  • How they relate: atomic defines the unit; on_commit hangs side effects off the boundary of that unit.

python

from django.db import transaction with transaction.atomic(): order = Order.objects.create(...) order.items.bulk_create(items) # only enqueue the task if the commit actually succeeds transaction.on_commit(lambda: send_order_email.delay(order.id))

Q37.
When would you use a custom Manager versus a custom QuerySet?

Mid

Use a custom QuerySet for reusable, chainable query logic, and a custom Manager for the entry point on the model (including non-chainable, table-level operations). In practice you write the logic on a QuerySet and expose it as the manager with Manager.from_queryset(), getting the best of both.

  • Custom QuerySet: chainable filters:

    • Methods return another queryset, so they compose: Article.objects.published().by_author(x).

    • The logic is reusable anywhere a queryset flows, including inside related lookups and prefetch_related.

  • Custom Manager: the access point:

    • Override get_queryset() to change the default set (e.g. a PublishedManager).

    • Good home for operations that don't fit chaining: bulk creation helpers, table-level aggregates, factory methods.

  • Combine them: Manager.from_queryset(MyQuerySet) copies the queryset methods onto a manager, so both Model.objects.published() and chaining work without duplicating code.

python

class ArticleQuerySet(models.QuerySet): def published(self): return self.filter(status="published") class Article(models.Model): status = models.CharField(max_length=20) objects = ArticleQuerySet.as_manager() # chainable + manager entry point

Q38.
When would you use a Custom Manager (models.Manager) instead of just writing methods on the Model class?

Mid

Use a custom Manager for table-level operations, things that act on the collection of rows (queries, factories, default filtering). Use model methods for row-level behavior that operates on a single instance. The distinction is scope: a manager answers "give me a set of objects," a model method answers "do something with this object."

  • Custom Manager: table/collection level:

    • Encapsulates reusable queries: Book.objects.published() instead of repeating .filter(status="published") everywhere.

    • Override get_queryset() to change the default set the model exposes.

    • Holds factory/creation helpers like a custom create_user().

  • Model method: instance level: Operates on self: order.total() or user.full_name().

  • Rule of thumb:

    • If the logic answers "which objects?" it belongs on a manager (or queryset); if it answers "what does this one object do?" it belongs on the model.

    • For chainable query logic prefer a custom QuerySet exposed via as_manager().

Q39.
How does Django's CSRF protection work conceptually, and what is the role of the hidden token in the form?

Mid

Django's CSRF protection uses a secret token that only your own site can produce, so a malicious site cannot forge a valid state-changing request on the user's behalf. The server checks that the token sent with the request matches the one tied to the user's session.

  • The problem CSRF solves: Browsers auto-attach cookies, so a forged request from another site would otherwise carry the victim's session and be accepted.

  • The token mechanism:

    • Django sets a CSRF secret (in a cookie via csrftoken, or in the session) and renders a matching token into the form.

    • On POST, CsrfViewMiddleware compares the submitted token against the cookie/session secret: a mismatch returns 403.

  • Role of the hidden field:

    • The {% csrf_token %} tag injects <input type="hidden" name="csrfmiddlewaretoken"> so the value travels in the request body, not just the cookie.

    • Because JavaScript on another domain can't read your cookie to copy the token, an attacker can't reproduce it.

  • For AJAX/APIs, the token is sent via the X-CSRFToken header instead of a form field.

Q40.
How does Django distinguish between authentication and authorization? Explain how the PermissionRequiredMixin works under the hood.

Mid

Authentication is verifying who you are (identity); authorization is deciding what you're allowed to do (permissions). Django keeps these separate: the auth system establishes request.user, and permission checks gate access afterward.

  • Authentication: Handled by authenticate() and login(); identifies the user and attaches them to the request.

  • Authorization: Driven by permissions like app.add_model, checked via user.has_perm().

  • How PermissionRequiredMixin works under the hood:

    1. You set permission_required (a string or list of permission codenames).

    2. Its dispatch() calls has_permission(), which runs request.user.has_perms(perms).

    3. If the user lacks them, it calls handle_no_permission(): redirect to login if anonymous, or raise PermissionDenied (403) if logged in.

Q41.
Explain the purpose of the User model and the trade-offs between AbstractUser and AbstractBaseUser when customizing authentication.

Mid

The User model represents an account: credentials, identity, and permission relationships. When customizing it, AbstractUser keeps Django's built-in fields and lets you add to them, while AbstractBaseUser gives you only the auth core so you design the schema from scratch.

  • Purpose of the User model: Stores credentials (hashed password), identity fields, and ties into permissions/groups for authorization.

  • AbstractUser:

    • Full concrete user with username, email, is_staff, permissions, etc.

    • Best when you just want to add or tweak a few fields with minimal effort.

  • AbstractBaseUser:

    • Provides only password handling and last_login; you define every other field, USERNAME_FIELD, and a custom manager.

    • Add PermissionsMixin if you want the standard permission framework.

    • Best when the identity model differs fundamentally (e.g. email-only login, no username).

  • Always set AUTH_USER_MODEL before the first migration: swapping it later is painful.

Q42.
Compare session-based authentication versus JWT — when would you use one over the other?

Mid

Session auth stores state on the server and identifies the client by a session cookie; JWT is stateless, carrying a signed, self-contained token that the server validates without a lookup. Choose sessions for traditional server-rendered apps, JWT for stateless/distributed APIs.

  • Session-based:

    • Server keeps session data; client holds only the session ID cookie.

    • Easy revocation (delete the session) and works seamlessly with Django's cookie + CSRF model.

    • Needs a shared session store when scaling across servers.

  • JWT:

    • Token is self-contained and signed; the server verifies the signature, no DB hit.

    • Great for stateless APIs, mobile clients, and microservices.

    • Hard to revoke before expiry; needs short lifetimes plus refresh tokens or a blocklist.

  • Rule of thumb: Server-rendered or single-domain app: sessions. Stateless API consumed by many clients or services: JWT.

Q43.
Explain how Django handles user authentication and sessions without storing passwords in plain text.

Mid

Django never stores raw passwords: it stores a salted, one-way hash, and on login it hashes the submitted password and compares hashes. Sessions then track the logged-in state so the password isn't re-sent on every request.

  • Password storage:

    • set_password() runs the configured hasher (default PBKDF2) with a random salt and stores algorithm$iterations$salt$hash.

    • Hashing is one-way: the original can't be recovered.

  • Login verification:

    • check_password() re-hashes the input with the stored salt/params and compares in constant time.

    • If the algorithm is outdated, Django transparently re-hashes on successful login.

  • Session linkage: login() stores the user's ID in the session; the browser then sends only the sessionid cookie, so the password is verified once, not repeatedly.

Q44.
What is the difference between Token Authentication and JWT in the context of a Django backend?

Mid

DRF's TokenAuthentication uses an opaque random string stored in the database that maps to a user; JWT is a self-contained, signed token whose claims the server validates cryptographically without a lookup. The key difference is stateful (server-stored) versus stateless (self-verifying).

  • Token Authentication (DRF):

    • A row in the authtoken table links a random key to a user.

    • Each request does a DB lookup; revoking is trivial (delete the row).

    • Carries no data and typically doesn't expire by default.

  • JWT:

    • Encodes claims (user id, expiry) in the token, signed with a secret/key.

    • Verified by checking the signature: no DB hit, good for scaling and microservices.

    • Built-in expiry; revocation before expiry needs refresh tokens or a blocklist (e.g. djangorestframework-simplejwt).

  • Trade-off: Tokens: simple and easily revoked but stateful. JWT: stateless and fast but harder to invalidate.

Q45.
With the introduction of async support in Django 5.x, when should you use async def for a view versus a standard def?

Mid

Use async def when your view does I/O through async-capable APIs (async ORM calls, httpx, external async services); use plain def for ordinary synchronous code or CPU-bound work.

  • async def views run on the event loop:

    • Worthwhile when you genuinely await concurrent I/O, e.g. fanning out multiple external calls with asyncio.gather().

    • Required for streaming responses and long-lived connections.

  • def views still run efficiently: Most CRUD views gain nothing from async since the sync ORM is mature and well-optimized.

  • Don't mix blocking calls into async: A blocking call inside async def stalls the event loop; wrap it with sync_to_async().

  • Rule of thumb: choose async only when the whole request path is async-aware, otherwise stay sync.

Q46.
What is the difference between @property and @cached_property in a Django model?

Mid

Both expose a method as an attribute, but @property recomputes on every access while @cached_property computes once per instance and stores the result, so repeated access is free.

  • @property:

    • Runs the method body on each access; always reflects current field values.

    • Use for cheap computations or when the underlying data can change between accesses.

  • @cached_property (from django.utils.functional):

    • Computes once, caches on the instance's __dict__, returns the stored value thereafter.

    • Ideal for expensive work like a DB query or aggregation accessed multiple times in a template/request.

  • The cache caveat:

    • The cache lives only as long as the instance; if data changes mid-request the stale value persists. Clear it with del obj.attr.

    • A cached_property must take no extra arguments (just self).

Q47.
What are the on_delete options for a ForeignKey (CASCADE, PROTECT, SET_NULL, etc.), and how do you decide which to use?

Mid

on_delete tells Django what to do to rows that point to an object when that object is deleted; it is required and chosen by what the relationship means for data integrity.

  • CASCADE: Delete the dependent rows too. Use when a child can't exist without its parent (e.g. comments on a deleted post).

  • PROTECT: Block the delete with ProtectedError. Use to prevent accidental loss of referenced data (e.g. don't delete a Category still in use).

  • SET_NULL: Set the FK to NULL; requires null=True. Use when the child survives orphaned (e.g. keep articles when an author is removed).

  • SET_DEFAULT / SET(...): Reassign to a default or a computed value (e.g. a "deleted user" sentinel).

  • DO_NOTHING: Django does nothing; you must handle integrity at the DB level yourself. Rarely used.

  • How to decide: Ask: does the child make sense without the parent? No → CASCADE. Yes → SET_NULL. Must never lose the data → PROTECT.

Q48.
How do you model a Many-to-Many relationship in Django, and when would you use an explicit 'through' model?

Mid

You declare a ManyToManyField and Django auto-creates a hidden join table; you add an explicit through model when the relationship itself needs to carry extra data.

  • Default M2M: Just add members = models.ManyToManyField(Person); Django manages the join table and gives you .add(), .remove(), .set().

  • Explicit through model:

    • Use when the link needs attributes (date joined, role, quantity, status).

    • You define a normal model with two FKs plus the extra fields, and set through= on the M2M.

    • Tradeoff: with a custom through you must create rows explicitly (.add() with extra fields is limited), creating the join object yourself.

  • Both query the same way: Use prefetch_related() to avoid N+1 queries when traversing the relation.

python

class Group(models.Model): name = models.CharField(max_length=100) members = models.ManyToManyField("Person", through="Membership") class Membership(models.Model): person = models.ForeignKey("Person", on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE) date_joined = models.DateField() role = models.CharField(max_length=50)

Q49.
What is the related_name attribute on a relationship field, and how does it affect reverse lookups?

Mid

related_name sets the attribute used to access a relationship in the reverse direction (from the target model back to the model that defines the FK or M2M).

  • Default reverse accessor: Without it, Django uses <model>_set (e.g. author.book_set.all()).

  • Custom name for readability: related_name="books" lets you write author.books.all().

  • Resolves clashes: When two FKs point to the same model, default names collide; distinct related_name values fix it.

  • Disabling the reverse relation: Set related_name="+" to prevent a reverse accessor entirely.

  • Also affects queries: The name is used in reverse filters too (use related_query_name to customize that separately): Author.objects.filter(books__title=...).

Q50.
What is a context processor in Django, and why would you use one instead of passing data directly through a view's context dictionary?

Mid

A context processor is a function that injects variables into the context of every template rendered with a RequestContext, so you set common data once instead of repeating it in every view's context dictionary.

  • How it works:

    • It takes the request and returns a dict; Django merges that dict into the context of every template render.

    • Registered under TEMPLATES['OPTIONS']['context_processors'] (e.g. the built-in ones add request, user, messages).

  • Why use one over per-view context:

    • DRY: data needed everywhere (site name, current user, nav menu, feature flags) is provided in one place rather than copied into hundreds of views.

    • Available in templates rendered by views you don't control or didn't write.

  • Tradeoffs:

    • It runs on every render, so keep it cheap; expensive DB work there taxes the whole site.

    • For data needed by only a few views, plain view context is clearer and avoids global overhead.

python

# myapp/context_processors.py def site_settings(request): return {"site_name": "Acme", "support_email": "help@acme.com"} # settings.py -> TEMPLATES['OPTIONS']['context_processors'] += # 'myapp.context_processors.site_settings' # Now {{ site_name }} is available in every template.

Q51.
How would you implement a custom middleware to log the time taken for every request, and what methods like process_view or process_response would you hook into?

Mid

Record a start time on the way in, then compute and attach the elapsed time on the way out: a plain callable middleware is enough, and you only need process_view if you want the resolved view name.

  • Capture timing in the callable: Store time.monotonic() before get_response(), measure the delta after it returns.

  • process_view (optional): Called after URL resolution with the view function and args, so it's where you'd log which view is being timed.

  • process_response / response phase: The right place to add an X-Request-Duration header or emit the log line.

  • Register it in MIDDLEWARE; place it near the top to capture the full stack's time.

python

import time, logging logger = logging.getLogger(__name__) class TimingMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): start = time.monotonic() response = self.get_response(request) duration = time.monotonic() - start response["X-Request-Duration"] = f"{duration:.3f}" logger.info("%s %s took %.3fs", request.method, request.path, duration) return response def process_view(self, request, view_func, view_args, view_kwargs): request._view_name = view_func.__name__

Q52.
Explain the concept of soft deletes and how you would implement it conceptually in Django.

Mid

A soft delete marks a row as deleted (typically a deleted_at timestamp or is_deleted flag) instead of physically removing it, so data is recoverable and history is preserved while it disappears from normal queries.

  • Add a marker field: A nullable deleted_at = models.DateTimeField(null=True); null means active.

  • Override delete behavior: Override the model's delete() to set the flag instead of hitting the DB.

  • Filter via a custom manager: A default manager that excludes deleted rows, plus a second manager (e.g. all_objects) that sees everything.

  • Watch the gotchas:

    • Unique constraints can clash with 'deleted' rows; use conditional/partial unique constraints.

    • Cascades, querysets in third-party code, and admin may bypass your manager.

    • Data grows indefinitely; plan periodic hard-purge or archiving.

python

class SoftDeleteManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(deleted_at__isnull=True) class Article(models.Model): deleted_at = models.DateTimeField(null=True, blank=True) objects = SoftDeleteManager() # active only all_objects = models.Manager() # includes deleted def delete(self, *args, **kwargs): self.deleted_at = timezone.now() self.save(update_fields=["deleted_at"])

Q53.
Are Django signals asynchronous by default? What are the risks of performing heavy processing like sending an email inside a post_save signal?

Mid

No: Django signals are synchronous and run in-process, in the same thread and transaction as the code that triggered them. So heavy work in a post_save receiver directly blocks and slows the request that saved the object.

  • Signals block the caller: The .save() call doesn't return until every receiver finishes.

  • Risks of sending email in post_save:

    • Latency: an SMTP round-trip adds seconds to the user's request.

    • Failure coupling: if the mail server errors, it can raise inside the save flow.

    • Transaction timing: post_save fires before commit, so you may email about data that later rolls back.

  • Do it safely:

    • Offload to a task queue (Celery, RQ) and just enqueue a job from the receiver.

    • Defer until commit with transaction.on_commit() so you only act on persisted data.

Q54.
How does Django protect against SQL Injection, Cross-Site Request Forgery (CSRF), and Cross-Site Scripting (XSS) by default?

Mid

Django defends against these three by default through its ORM, a CSRF middleware with per-request tokens, and template auto-escaping: each addresses a different attack surface, and they're on out of the box.

  • SQL Injection:

    • The ORM uses parameterized queries: values are passed separately from SQL, never string-concatenated.

    • Risk returns only with raw SQL (.raw(), cursor.execute) if you build strings manually instead of using params.

  • CSRF:

    • CsrfViewMiddleware requires a secret token ({% csrf_token %}) on unsafe methods (POST/PUT/DELETE).

    • An attacker's cross-site form can't read or forge the token.

  • XSS:

    • The template engine auto-escapes variables, converting characters like < and & to HTML entities.

    • You opt out explicitly with |safe or mark_safe(), which is where you reintroduce risk.

  • Caveat: these are defaults, not guarantees: raw SQL, @csrf_exempt, and mark_safe can each disable the protection.

Q55.
How does Django's caching framework work, and what are the trade-offs between Per-View caching and Template Fragment caching?

Mid

Django's cache framework offers a pluggable backend (Redis, Memcached, DB, local memory) accessed through one API, plus several granularities of caching. Per-view caching stores an entire rendered response, while template fragment caching stores just a piece of a template, trading simplicity against flexibility.

  • How it works:

    • Configure CACHES with a backend; use the low-level API (cache.get/set) or higher-level helpers.

    • Granularities: whole-site middleware, per-view, template fragment, and low-level object caching.

  • Per-view caching:

    • @cache_page(timeout) caches the full response keyed by URL (and varying headers).

    • Pro: simple and fast, skips view and DB work entirely.

    • Con: all-or-nothing, so it's wrong for pages with per-user or dynamic sections.

  • Template fragment caching:

    • {% cache timeout name var %} caches one block, so the rest of the page stays dynamic.

    • Pro: cache expensive widgets (a sidebar, a list) while keeping personalized parts live.

    • Con: the view and template still execute, so you save less than a full-page cache.

  • Rule of thumb: page is mostly static, use cache_page; page is dynamic with a few heavy parts, use fragment caching.

Q56.
What are the tradeoffs between Function-Based Views and Class-Based Views? In what scenario is an FBV actually more maintainable than a CBV?

Mid

FBVs are plain functions: explicit, linear, easy to read; CBVs use class inheritance and mixins to reuse boilerplate but hide logic in the parent hierarchy. FBVs win when a view is simple or highly custom; CBVs win when you reuse common CRUD patterns.

  • Function-Based Views:

    • Pro: flow is top-to-bottom and explicit, so behavior is obvious without consulting base classes.

    • Con: reusing logic across views means copy-paste or manual helper functions.

  • Class-Based Views:

    • Pro: built-in generics (ListView, CreateView) remove repetitive CRUD boilerplate via mixins.

    • Con: behavior is spread across the MRO, so debugging requires knowing which method (get_queryset(), dispatch()) to override.

  • When an FBV is more maintainable:

    • A view with branching, custom logic that doesn't map cleanly onto a generic pattern: forcing it into CBV method overrides scatters the logic and obscures it.

    • A simple one-off endpoint where a CBV adds ceremony without saving code.

Q57.
Explain the new 'Field Group' feature in Django 5.0 templates. How does it change the way we render forms compared to previous versions?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q58.
What are the different ways to implement Rate Limiting in a Django application?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q59.
When should you use Django's built-in Generic Views like ListView or DetailView versus writing a custom view from scratch?

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q60.
When does a Django application 'need' Celery or Redis? Explain the concept of decoupling a request from a long-running background task.

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q61.
How do Django Forms validate data? Explain the role of clean(), clean_<field>(), and is_valid().

Mid
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q62.
How does Django's internal 'App Registry' work, and why is the ready() method in apps.py significant?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q63.
How do you handle idempotency in Django REST APIs, especially for payment or order endpoints?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q64.
Django does not have built-in connection pooling. Why is this a problem for high-concurrency applications, and what architectural solutions like PgBouncer are typically used?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q65.
What is a 'Database Router' in Django, and in what scenario would you need to implement one?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q66.
Explain the difference between WSGI and ASGI. When would you choose one over the other in a modern Django 5.x environment?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q67.
What happens if you call a synchronous ORM method inside an asynchronous view? How does Django 5.x handle this?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q68.
If you were building a high-concurrency real-time notification system, would you use standard Django, Django Channels, or a separate framework like FastAPI? Why?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q69.
When would you choose an ASGI server like Uvicorn over a WSGI server like Gunicorn for a Django project? What are the implications for handling WebSockets or long-running tasks?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q70.
Explain the different types of Model Inheritance in Django (Abstract Base Classes, Multi-table inheritance, and Proxy models) and the database-level implications of each.

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q71.
What are the tradeoffs of using 'Generic Foreign Keys' (the ContentType framework) versus standard Foreign Keys?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q72.
How does Django handle database-level constraints versus application-level validation? Why might you use UniqueConstraint in a Meta class instead of just unique=True on a field?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q73.
What is the advantage of using Django 5.0's GeneratedField to have the database calculate a field value versus doing it in the Python save() method?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q74.
What are the tradeoffs of using Abstract Base Classes vs Multi-table Inheritance in Django models?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q75.
What are Django Signals, and why are they often considered a 'hidden' dependency or an anti-pattern in large systems?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.

Q76.
What is the 'Fat Models, Thin Views' philosophy? Under what circumstances might you move logic out of the model and into a 'Service Layer'?

Senior
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.