Series Review#

This is the 30th article in the Django Ninja tutorial series.
In the final chapter of the series, our "Django Ninja Adventure" will temporarily come to a close.
This is certainly not the end; after all, Django Ninja is still a relatively new project—I am full of expectations for its future.
This article will be divided into two parts:
- Review the entire series, examining the concepts and techniques we learned in each chapter—focusing only on the key points as much as possible.
- Share the biggest challenges I faced while writing, my expectations for Django Ninja, and my final reflections on the iThome Ironman Contest.
Due to space limitations, I will share more behind-the-scenes stories, creative details, and personal feelings in Articles 31 and 32, which are unrelated to the main competition.
In addition, I will update "Django Ninja Side Stories" from time to time to supplement what was not detailed in the main chapters. For interested readers, welcome to subscribe to this series or our site email newsletter.
Without further ado, let's get started.
GitHub Example Project#
1. Series Goals and Key Learning Outcomes#
Going back to the beginning of Article 1, the goal of the entire series was:
In this 30-day article series, we will explore the basic implementation of Django Ninja in detail. Through textual tutorials and code from the example project, we will guide you step-by-step to familiarize yourself with this powerful and flexible Django API development framework.
Exactly, and what did we do concretely?
Key Learning Outcomes#
Through this series, readers have mastered the following core skills of Django Ninja:
- Configuring Django Ninja Routing. (Articles 7-8)
- Handling HTTP Requests and their Path Parameters, Query Parameters, and bodies. (Articles 9-12)
- Designing and defining API Response structures with Schema. (Articles 13-16)
- Generating API Documentation from code, validating data with Pydantic, and handling errors effectively. (Articles 17-22)
- Applying advanced features, including File Uploads, Pagination, and data filtering. (Articles 23-27)
And finally, authentication and unit testing. It can be said to be a fairly complete journey.
The subtleties and difficulties will not be repeated here.
Let's review some key points of learning Django Ninja, as well as the satisfaction it brings—which is very important!
2. Review of Key Points in Each Chapter#
We will only pick sections that are particularly worth mentioning in each chapter, which include my personal viewpoints.
Chapter 2: Example Project and Environment Configuration#
The most important part of this chapter is the introduction of "modern Python development tools." Again, I recommend the "Python Table Manners" series.
From Poetry to Mypy, I believe these tools are essential elements in modern projects. Each has alternatives, and you can choose the tools you prefer, as long as you make sure these elements are integrated into your development workflow.
I believe that no matter how AI develops, the "infrastructure" of a project is always indispensable.
Chapter 3 Section 1: Routers#
The routing configuration of Django Ninja is very different from traditional Django and Django REST framework.
In this regard, latecomers basically look up to the "routing decorators" pioneered by Flask—excellent designs are worth borrowing and learning from each other 🫡.
The new syntax is not only simpler and more intuitive but also prevents Routing configuration from being scattered across different files.
However, routing has therefore become a small threshold when learning Django Ninja at the beginning. That's why I spent two full articles comparing the differences between the two, so that you can clearly understand the thoughts and considerations.
Chapter 3 Section 3: HTTP Response#
On the surface, it is about HTTP response, but the key is introducing Django Ninja Schema—namely Pydantic BaseModel.
It is no exaggeration to say that this section is a "Pydantic Introduction."
An understanding of Pydantic remains important in later chapters on API Documentation and Data Validation. It is the foundation of everything that follows.
Django Ninja uses Schema to organize and serialize HTTP responses, which is essentially no different from the serializers used in Django REST framework.
However, their different design philosophies led to completely different development experiences. I wrote my main observations in "Article 15: Response (Part 3) Why Not ModelSchema? - Why I Prefer Django Ninja Over DRF," which is worth revisiting.
Chapter 4: API Documentation#
What else is there to say? It is too critical!
Without the killer feature of "generating API Documentation automatically from code and Type Hints," why would a developer accustomed to Django REST framework be motivated to learn a new framework with a similar purpose?
Laziness is the driver of everything!
Chapter 5: Data Validation and Error Handling#
This chapter is my blood and tears 😂.
Django Ninja's data validation and error handling methods are very different from Django REST framework. What made it more headache-inducing was that in my previous work, I didn't implement it in the "most standard" way—still influenced by Django REST framework development habits.
At that time I thought, "This is too difficult to use!"—turns out I misunderstood it myself. To write these 4 articles well, I almost re-learned it. I must say, there was a feeling of sudden enlightenment.
Therefore, the implementations you see in this series should be reasonable and idiomatic. Combined with experience, I've trodden all those pitfalls for you, so please don't worry.
Next is the personal reflections part.
3. The Biggest Challenge in Writing#
I think the biggest challenge in creating the entire series was to match the articles with the code in the GitHub project to provide a competent and coherent example.
(Needless to say, this project highly welcomes "stars from you" 🌟!)
This is much more troublesome than simply giving examples. I had to plan the progress of the entire series beforehand, thinking about how the API implementation would align with the theme of each article to bring a "sense of immersion."
In addition, the coherence of the narrative must be considered—the code must be progressive, from simple to complex, rather than the other way around. This way, readers can smoothly learn along with the project.
Such planning requires not only technical knowledge but also teaching thinking and reader awareness—knowing where readers might get "stuck."
Overall, it was an extremely challenging but very interesting process.
4. My Evaluation and Expectations of Django Ninja#
Django Ninja is an open-source project maintained solely by Ukrainian developer Vitaliy Kucheryaviy. The update frequency is not high, and it usually cannot instantly respond to users' expectations.
But I want to say: "If possible, I really don't want to go back to writing Django REST framework anymore."
There is only one reason, which is what was mentioned in Article 15—"Explicit is better than implicit."
Django Ninja might not make development "faster," but it is definitely more transparent and controllable.
I believe that in the long run, the time saved in debugging due to this transparency and controllability is far beyond what simple "speed" can compare to.
Future Expectations#
With Django itself providing increasing support for asynchronous operations (async), I believe the potential of Django Ninja is being progressively unlocked.
I expect that in the near future, when people talk about "writing APIs with Django," they will no longer think only of Django REST framework, but will also mention this powerful new option—Django Ninja.
5. Completion Reflections#
Phew! Finally finished. This process was longer than I imagined.
From early September to Double Tenth Day, for a full 40 days (including prep before the competition), I woke up every morning writing, throwing myself wholeheartedly into this feast. In the end, I delivered a piece of work that I myself was satisfied with.
In my view, the satisfaction of writing lies in "providing value and exercising influence." This value is not only for the readers but also for the author himself—through creating these 30 articles, my understanding of Django Ninja has improved significantly.
I hope this series can bring you some value, making you more comfortable in your upcoming development journey.
Every writing is a learning experience, and every learning experience is a growth. This series might have ended, but our path as software engineers is far from over.
And if possible, I hope this can become a lifelong pursuit.