StackScholar
  • System Design Interview Preparation

    Beginner to advanced, with interactive simulators and full design case studies.

  • Python Full-Stack Interview Preparation

    Master backend + frontend questions with real-world cases.

  • AI/ML Engineer Interview Preparation

    ML, deep learning, LLMs, RAG, MLOps and system design - with mock interviews.

Rapid Review CSnewDSA VisualizerReviewBlog
Search⌘K
System Design Interview PreparationPython Full-Stack Interview PreparationAI/ML Engineer Interview Preparation
Rapid Review CSnewDSA VisualizerReviewBlog
CurriculumAll questionsFlashcardsGlossaryVisualizersDSA Visualizer

Navigate by Range

  • Q&A Python-1-5
  • Q&A Python-6-10
  • Q&A Python-11-15
  • Q&A Python-16-20
  • Q&A Python-21-25
  • Q&A Python-26-30
  • Q&A Python-31-35
  • Q&A Python-36-40
  • Q&A Python-41-45
  • Q&A Python-46-50
  • Q&A Python-51-55
  • Q&A Python-56-60
  • Q&A Python-61-65
  • Q&A Python-66-70
  • Q&A Python-71-75
  • Q&A Python-76-80
  • Q&A Python-81-85
  • Q&A Python-86-90
  • Q&A DB-MySQL-1-5
  • Q&A DB-MySQL-6-10
  • Q&A DB-MySQL-11-15
  • Q&A DB-MySQL-16-20
  • Q&A DB-MySQL-21-25
  • Q&A DB-MySQL-26-30
  • Q&A DB-MySQL-31-35
  • Q&A DB-MySQL-36-40
  • Q&A DB-MySQL-41-45
  • Q&A DB-MySQL-46-50
  • Q&A Django-1-5
  • Q&A Django-6-10
  • Q&A Django-11-15
  • Q&A Django-16-20
  • Q&A Django-21-25
  • Q&A Django-26-30
  • Q&A Django-31-35
  • Q&A Django-36-40
  • Q&A Django-41-45
  • Q&A Django-46-50
  • Q&A FastAPI-01-05
  • Q&A FastAPI-06-10
  • Q&A FastAPI-11-15
  • Q&A FastAPI-16-20
  • Q&A FastAPI-21-25
  • Q&A FastAPI-26-30
  • Q&A FastAPI-36-40
  • Q&A FastAPI-41-45
  • Q&A FastAPI-31-35
  • Q&A FastAPI-46-50
  • Q&A FastAPI-51-55
  • Q&A FastAPI-56-60
  • Q&A FastAPI-61-65
  • Q&A HTML-01-05
  • Q&A HTML-06-10
  • Q&A HTML-11-15
  • Q&A HTML-16-20
  • Q&A CSS-01-05
  • Q&A CSS-06-10
  • Q&A CSS-11-15
  • Q&A CSS-16-20
  • Q&A JavaScript-1-5
  • Q&A JavaScript-6-10
  • Q&A JavaScript-11-15
  • Q&A JavaScript-16-20
  • Q&A JavaScript-21-25
  • Q&A JavaScript-26-30
  • Q&A JavaScript-31-35
  • Q&A JavaScript-36-40
  • Q&A JavaScript-41-45
  • Q&A JavaScript-46-50
  • Q&A React-1-5
  • Q&A React-6-10
  • Q&A React-11-15
  • Q&A React-16-20
  • Q&A React-21-25
Loading…

Navigate by Range

  • Q&A Python-1-5
  • Q&A Python-6-10
  • Q&A Python-11-15
  • Q&A Python-16-20
  • Q&A Python-21-25
  • Q&A Python-26-30
  • Q&A Python-31-35
  • Q&A Python-36-40
  • Q&A Python-41-45
  • Q&A Python-46-50
  • Q&A Python-51-55
  • Q&A Python-56-60
  • Q&A Python-61-65
  • Q&A Python-66-70
  • Q&A Python-71-75
  • Q&A Python-76-80
  • Q&A Python-81-85
  • Q&A Python-86-90
  • Q&A DB-MySQL-1-5
  • Q&A DB-MySQL-6-10
  • Q&A DB-MySQL-11-15
  • Q&A DB-MySQL-16-20
  • Q&A DB-MySQL-21-25
  • Q&A DB-MySQL-26-30
  • Q&A DB-MySQL-31-35
  • Q&A DB-MySQL-36-40
  • Q&A DB-MySQL-41-45
  • Q&A DB-MySQL-46-50
  • Q&A Django-1-5
  • Q&A Django-6-10
  • Q&A Django-11-15
  • Q&A Django-16-20
  • Q&A Django-21-25
  • Q&A Django-26-30
  • Q&A Django-31-35
  • Q&A Django-36-40
  • Q&A Django-41-45
  • Q&A Django-46-50
  • Q&A FastAPI-01-05
  • Q&A FastAPI-06-10
  • Q&A FastAPI-11-15
  • Q&A FastAPI-16-20
  • Q&A FastAPI-21-25
  • Q&A FastAPI-26-30
  • Q&A FastAPI-36-40
  • Q&A FastAPI-41-45
  • Q&A FastAPI-31-35
  • Q&A FastAPI-46-50
  • Q&A FastAPI-51-55
  • Q&A FastAPI-56-60
  • Q&A FastAPI-61-65
  • Q&A HTML-01-05
  • Q&A HTML-06-10
  • Q&A HTML-11-15
  • Q&A HTML-16-20
  • Q&A CSS-01-05
  • Q&A CSS-06-10
  • Q&A CSS-11-15
  • Q&A CSS-16-20
  • Q&A JavaScript-1-5
  • Q&A JavaScript-6-10
  • Q&A JavaScript-11-15
  • Q&A JavaScript-16-20
  • Q&A JavaScript-21-25
  • Q&A JavaScript-26-30
  • Q&A JavaScript-31-35
  • Q&A JavaScript-36-40
  • Q&A JavaScript-41-45
  • Q&A JavaScript-46-50
  • Q&A React-1-5
  • Q&A React-6-10
  • Q&A React-11-15
  • Q&A React-16-20
  • Q&A React-21-25
StackScholar

StackScholar is your go-to destination for exploring technology from every angle - from bit to supercomputer.

Quick Links

  • Home
  • Search
  • Daily Review
  • Blog
  • About
  • Contact
  • Privacy Policy

DSA Visualizer

  • DSA Visualizer
  • Sorting Algorithms
  • Binary Search Tree
  • Dijkstra's Algorithm
  • A* Pathfinding
  • Dynamic Programming

Rapid Review CS

  • Rapid Review CS
  • Operating Systems
  • DBMS
  • Computer Networks
  • Data Structures & Algorithms
  • Computer Architecture

Interview Preparation

  • System Design Interview
  • System Design Toolkit
  • System Design Patterns
  • Python Full-Stack Interview
  • AI/ML Engineer Interview
  • ML Mock Interview
  • AI/ML Glossary

Get new lessons and visualizers in your inbox

Occasional email when something substantial ships. No spam, unsubscribe anytime.

© 2026 StackScholar. All rights reserved.

Django Interview Questions 31-35 (Async, Testing, DRF Basics)

Hello! We've covered a lot of ground in Django, from the basics of MVT and models to more advanced features like security and caching. Now, we're going to bridge the gap between a traditional Django app and a modern, high-performance API.

This lesson covers some vital modern topics. We'll start with Django's new asynchronous capabilities. Then, we'll cover the essentials of testing, a non-negotiable skill for professional developers. Finally, we'll begin our deep dive into the most popular Django add-on: Django REST Framework (DRF), the tool you'll use to build powerful web APIs.

31. Explain Django’s asynchronous support. (Views, ORM limitations)

This is a modern Django feature. Traditionally, Django was purely synchronous. When a request came in, it was handled by one worker thread from start to finish. If that thread had to wait (e.g., for a slow database query or an external API call), it was blocked and couldn't do any other work.

Analogy: The Barista

  • Synchronous Django (Old way): You have one barista. When a customer orders a complex latte, the barista makes the espresso, steams the milk, and hands it over. While the espresso is pulling (an I/O wait), the barista just stands there, blocked. The entire line of customers has to wait.
  • Asynchronous Django (New way): You have an async barista. When a customer orders, the barista starts the espresso machine (`await pull_espresso()`). Instead of waiting, they immediately move to the next customer and take their order. When the espresso is ready, the machine sends a signal, and the barista picks it up when they have a free moment. They can handle many customers concurrently.

Django now supports async views by running on an ASGI (Asynchronous Server Gateway Interface) server like Uvicorn. This is ideal for tasks that are I/O-bound (like making many external API calls at once).

The `async` View:

import asyncio
from django.http import HttpResponse

# By defining the view with 'async def',
# Django knows to run it in an async context.
async def my_async_view(request):
    # This allows other tasks to run
    # while we are 'sleeping' (waiting for I/O).
    await asyncio.sleep(5)
    
    return HttpResponse("Done after 5 seconds!")

The ORM story (this changed - do not give the old answer)

You still cannot write await Product.objects.all(), but not for the reason people usually give. A QuerySet is lazy - it is a query builder, not a coroutine - so there is nothing to await until you actually evaluate it.

Since Django 4.1 the ORM has a proper async query API: the same methods with an a prefix, plus async iteration. Django 5.0 extended this to related managers. So the old advice of “you must always wrap ORM calls in sync_to_async” is out of date.

from .models import Product

async def product_views():
    # Async versions of the terminal methods (Django 4.1+)
    product = await Product.objects.aget(pk=1)
    count   = await Product.objects.acount()
    exists  = await Product.objects.filter(active=True).aexists()
    first   = await Product.objects.order_by("name").afirst()

    await Product.objects.acreate(name="Widget", price=9.99)
    product.price = 12.50
    await product.asave()
    await product.adelete()

    # Iterating a queryset asynchronously
    async for p in Product.objects.filter(active=True):
        print(p.name)

    # Async comprehension to materialise a list
    names = [p.name async for p in Product.objects.all()]
    return names

The nuance that gets you the follow-up right: these async methods are an async-safe interface, not async database drivers. Django still executes the query on a thread under the hood, so you get correctness and clean syntax inside an event loop, but not the connection-level concurrency you would get from an natively async stack like SQLAlchemy's asyncio extension. Fully async database backends are still work in progress.

sync_to_async is still the right tool for ORM operations that have no a-prefixed variant, and for any other blocking work you need to call from async code:

from asgiref.sync import sync_to_async

# Still needed for sync-only code paths, e.g. a third-party
# library or a method without an async variant.
result = await sync_to_async(some_blocking_function)(arg)

32. How do you write unit tests in Django?

Django has a powerful built-in testing framework that is an extension of Python's standard `unittest` module.

A unit test is a function that tests one small, isolated "unit" of your code (e.g., "Does my `Product` model correctly calculate its sale price?").

The key features of Django's testing are:

  • Test Database: When you run tests, Django automatically creates a brand new, blank test database. This ensures your tests are isolated and don't destroy your real data.
  • `TestCase`: You write tests by subclassing `django.test.TestCase`. This class provides helpful tools, like an`self.client` object.
  • `self.client`: This is a dummy web browser that lets you "pretend" to be a user. You can use it to `self.client.get('/my-url/')` or `self.client.post(...)` and then check the response.
# my_app/tests.py
from django.test import TestCase
from django.urls import reverse
from .models import Product

class ProductTests(TestCase):

    # This 'setUp' method runs *before* every test
    def setUp(self):
        # Create a sample product to test against
        Product.objects.create(name="Test Product", price=100)

    def test_product_model_str(self):
        """Test the model's __str__ method."""
        product = Product.objects.get(name="Test Product")
        self.assertEqual(str(product), "Test Product")

    def test_product_list_view(self):
        """Test that the product list page loads."""
        # 'reverse' finds the URL from its name
        url = reverse('product-list') 
        
        # Use the test client to make a GET request
        response = self.client.get(url)
        
        # Check that the page loaded successfully
        self.assertEqual(response.status_code, 200)
        
        # Check that our product's name is in the HTML
        self.assertContains(response, "Test Product")

# To run the tests for 'my_app':
# $ python manage.py test my_app

Sample Output:

Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..
----------------------------------------------------------------------
Ran 2 tests in 0.042s

OK
Destroying test database for alias 'default'...

33. What is Django REST Framework (DRF)?

Django REST Framework (DRF) is a powerful and flexible toolkit for building Web APIs in Django.

While standard Django is built to return HTML (web pages), DRF is built to return data (like `JSON` or `XML`).

Analogy: The Restaurant, Revisited

  • Standard Django: Is a sit-down restaurant. It takes your order (request) and returns a fully-plated meal (an HTML web page) for you to consume.
  • DRF: Is a food delivery service. It takes your order (request) and returns the raw, un-plated food in a box (`JSON` data). This allows other applications (like a mobile app, a JavaScript frontend, or another backend) to consume your data and present it however they want.

DRF provides all the "batteries-included" features Django is famous for, but for APIs:

  • Serializers (for converting data)
  • Authentication (e.g., token, OAuth)
  • Permissions (e.g., "Is this user the owner of this post?")
  • Browsable API (a user-friendly website for testing your API)

34. What are serializers in DRF? Types of serializers.

A Serializer is the translator in DRF. Its job is to convert complex data types, like Django model instances, into native Python datatypes (like dictionaries) that can then be easily rendered into `JSON`.

It also does the reverse: deserialization. It takes incoming `JSON` data, validates it, and converts it back into a Python object or model instance.

Types of Serializers

The two main types are just like Django's forms:

  • `Serializer`: A generic class where you must manually define every field. Good for data that doesn't map to a model.
  • `ModelSerializer`: This is the magic. It automatically generates fields, validators, and `.save()` methods for you just by looking at your linked `Model`. You use this 95% of the time.
# my_app/serializers.py
from rest_framework import serializers
from .models import Product

# This ModelSerializer will:
# 1. Automatically create 'name' and 'price' fields
# 2. Automatically validate them (e.g., is 'price' a decimal?)
# 3. Automatically provide .create() and .update() methods
class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'price', 'in_stock']

# --- How it's used in practice ---

# SERIALIZATION (Object -> JSON)
product = Product.objects.get(pk=1)
serializer = ProductSerializer(product)
print(serializer.data)
# Output:
# {'id': 1, 'name': 'Test Product', 'price': '100.00', 'in_stock': True}


# DESERIALIZATION (JSON -> Object)
json_data = {'name': 'New Product', 'price': '50.00'}
serializer = ProductSerializer(data=json_data)
if serializer.is_valid():
    new_product = serializer.save()
    print(f"Created: {new_product.name}")
# Output:
# Created: New Product

35. Explain DRF ViewSets and Routers.

ViewSets and Routers are a set of conventions in DRF that let you write a full, working CRUD (Create, Read, Update, Delete) API with almost no code.

`ViewSet`

A `ViewSet` is a single class that combines the logic for a set of related views. Instead of writing a `ProductListView`, a `ProductDetailView`, and a `ProductCreateView`, you just write one `ProductViewSet`.

It doesn't have `.get()` or `.post()` methods. Instead, it has methods that map to database actions:`.list()`, `.retrieve()`, `.create()`, `.update()`, `.destroy()`.

`Router`

A `Router` is what connects a `ViewSet` to your `urls.py` file. You tell the router about your ViewSet, and it automatically generates all the URL patterns for you.

# my_app/views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer

# This ONE class provides all 5 CRUD operations
class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    # ...add permissions, authentication, etc.


# my_project/urls.py
from rest_framework.routers import DefaultRouter
from my_app.views import ProductViewSet

# 1. Create a router
router = DefaultRouter()

# 2. Register our ViewSet with the router
router.register(r'products', ProductViewSet, basename='product')

# 3. 'router.urls' now contains a full set of URLs
urlpatterns = [
    # ... your other urls ...
    path('api/', include(router.urls)),
]

# The router has now automatically generated:
# /api/products/       -> .list() (GET) and .create() (POST)
# /api/products/{pk}/  -> .retrieve() (GET), .update() (PUT),
#                         .partial_update() (PATCH), 
#                         and .destroy() (DELETE)

Tip: The combination of `ModelSerializer`, `ModelViewSet`, and `Router` is the core of DRF. It lets you write a complete, production-ready JSON API for a model in as little as 3-5 lines of code.

Check your understanding

2 questions · no sign-up, nothing stored

0/2 answered
Question 1

1.Inside an async Django view, how do you fetch one object?

Question 2

2.What is true about Django's async ORM methods?

0 / 74 ranges

Progress is stored in this browser only - no sign-up, nothing sent anywhere.

PreviousNext