Skip to content

HTTP Requests Overview#

2024 iThome Ironman

This is the 9th post in the Django Ninja tutorial series.

Welcome to Chapter 3, Section 2!

As the core implementation of API logic, the view function is undoubtedly the soul of a Django Ninja API.

Like FastAPI and Flask, Django Ninja primarily uses function-based views (hereafter, FBVs). Learning Django Ninja therefore largely revolves around the inputs and outputs of view functions.

In other words, Django Ninja's capabilities center on several key aspects of view functions, including:

  1. Handling HTTP request parameters and body.
  2. Handling HTTP response serialization and formatting.
  3. Data validation and error handling.

Together, they constitute the main features of Django Ninja.

This section and the next will focus on the first two of the three points mentioned above—requests and responses. The third point will be introduced in Chapter 5.

GitHub Example Project#

👉 Django-Ninja-Tutorial


Section Navigation#

Following the "Routing" section, this section will explore how Django Ninja handles HTTP requests—how to parse paths, URL query parameters, and bodies.

This section contains 4 articles:

In addition, because the view function's request-handling feature involves how Django Ninja uses type hints to validate request data, our example code will start incorporating Python type hints.

The syntax for type hints is based on Python 3.12.

Official Documentation#

The writing of this series references the "Django Ninja Official Documentation" from time to time, especially for the structure.

However, the documentation is meant for all developers and does not fully consider the learning sequence.

Since this series is primarily aimed at beginners, we will focus more on practical operations and the needs of beginners, and supplement background knowledge at appropriate times to ensure a relatively smooth learning curve.

In addition, for the framework itself, we will provide more examples and explanations to make new concepts easier to understand and master.

In any case, the official documentation remains something you need to refer to constantly when using Django Ninja—even though it is written much more "simply" compared to Django or Django REST framework documentation!


Main Objectives of This Article#

As an overview of the second section, this article aims to give you a basic understanding of Django Ninja's view functions and how they handle HTTP requests.

We will help you get familiar step-by-step through the following three key points:

  1. Advantages of FBVs.
  2. Django Ninja's processing flow for HTTP requests.
  3. The tight integration between Django Ninja and Type Hints.

Without further ado, let's get started.


Class-based views (CBVs) and FBVs are both means of implementing Views in the Django MTV Architecture, each with its own applicable scenarios.

CBVs offer code reusability, making them suitable for large projects. FBVs, meanwhile, are simple and straightforward, making it easy to develop small and medium-sized projects quickly.

For a comparison between the two, please refer to this article: Day27: CBV vs. FBV.

Since Django Ninja adopts FBVs, this article will only discuss the advantages of FBVs.

1. Advantages of FBVs#

FBVs are the view format used by Django Ninja. Compared to CBVs, FBVs are more concise and flexible, allowing developers to easily write API logic without needing to know too much background knowledge, such as "how to correctly override a certain CBV attribute."

Conciseness and Flexibility#

FBVs do not require inheriting or overriding class methods; all logic is concentrated in a single function.

This makes writing and maintaining code more intuitive.

Since an FBV is simply a function, it can apply different logic and conditions flexibly. Developers can control the entire request-processing flow in a single function without having to consider class structures or inheritance relationships.

Easy Debugging#

FBVs' code is relatively intuitive, making it easier for beginners to read and understand. When an error occurs, you can quickly pinpoint the issue, which is a convenience not easily achieved with CBVs.

My Perspective#

Django is a full-featured framework, but it is often criticized for being "heavy." FBVs alleviate this heaviness to some extent.

Imagine a beginner who has just started learning Django. After understanding the environment settings of various frameworks, having to dive deep into the world of CBVs might be too overwhelming.

In short, if you ask me, I definitely prefer FBVs—and "lightweight" is the trend in modern development.


2. Django Ninja's Processing Flow for HTTP Requests#

Django Ninja's processing of "requests" can be divided into several key steps:

  1. Route Matching: When a request comes in, the framework first matches the incoming URL with the defined path rules (endpoints). If matched successfully, it passes the HTTP request and related parameters to the view function.
  2. Parameter Parsing: Extracting path parameters and query parameters from the URL and converting them into "arguments" of the view function. It automatically performs type conversion and validation based on the function's type hints.
  3. Request Body Processing: For requests with a body such as POST or PUT, Django Ninja allows developers to define body data models using Schema (Pydantic BaseModel) and automatically maps the incoming data to these models.

Django Ninja HTTP Request Processing Flow

Point 1 above has been explained in detail in Chapter 3, Section 1.

Points 2 and 3 are the main content of the 4 articles in this section.


3. The Tight Integration Between Django Ninja and Type Hints#

Django Ninja heavily relies on Python's type hints to handle data in HTTP requests.

It achieves automatic data validation and type conversion via Pydantic, reducing the developer's burden of manually checking and converting data.

For example, the following code:

@router.get("/posts/{post_id}")
def get_post(request, post_id: int):
    return {"post_id": post_id}

When the post_id parameter is type-hinted as int, Django Ninja performs type checking. If the passed parameter cannot be converted to int, the framework directly returns an HTTP response with a 422 status code.

In other words, if you hint post_id as str, Django Ninja will automatically convert post_id to a string.

I remember when I first started using Django Ninja, I was amazed that Python type hints could be fully utilized to this extent—making them not just for type safety, but integrated into the entire API development process.

The Request Parameter in View Functions#

In the example above, there is a noteworthy detail, which is the first parameter of the view function—request.

In Django, the first parameter of a view function must be request. This parameter name can be defined arbitrarily, but it is usually named request.

When receiving an HTTP request, Django packages the entire request into an HttpRequest object and passes it as the first parameter to the view function, so it is indispensable.

Related article: Introduction to Common Attributes of Django HttpRequest

The request parameter is very important in Django and Django REST framework because it is commonly used to retrieve request query parameters, body, and other contents.

In Django Ninja, these data are retrieved directly through function parameters. Therefore, although request is still necessary, its usage frequency is lower.


Next Steps#

Next, we will explore the specific details of how Django Ninja handles requests.

The next article will focus on path parameters and discuss how to use them with Django's native path converters. Stay tuned!