Django Decorator Best Practice
Prologue
As a Web backend framework, Django is easy to use. However, simplicity is at the same time one of its drawbacks, which means it may not be that graceful for more complex requests. So in this post, I’m going to introduce a more elegant way to handle request parameters.
Write Your Own Decorator
1. Basic Decorator
Decorators in Django may seem to be mysterious when you first use it, just a simple @decorator
and some magic happens. So how can we implement ours?
A basic decorator can be as simple as this.
1 | from functools import wraps |
A little wired? Well, you can just focus on the logic, and take others as a template. If you want IDE to recognize the type of request
, you can add WSGIRequest
type hint.
1 | from django.core.handlers.wsgi import WSGIRequest |
For this decorator, you can use it like this.
1 |
|
Not that bad, huh? 😃 It is essentially a function, that’s it.
2. Response Before View
You may not want some illegal requests go into your view function, thus return Bad Request response in decorator can be a good choice. To achieve this, simply return such response instead of view_func
.
1 | from http import HTTPStatus |
3. Decorator with Parameters
To add parameters to our decorator, we simply add parameters to our decorator. 😳
1 | def message_decorator(message): |
See, that’s it, no difference from other ordinary functions.
4. Inject Parameters to View Function
You may want to get some data from the request in decorator, so that you won’t bother get it again and again in view function. To achieve this, you need *args
and *kwargs
in Python.
Previously, when we call view_func
, we pass only request
, *args
, **kwargs
. These are inherited from parent wrapper.
Notice that, decorators are like middlewares, they will process the request one by one. The parameters you set in one decorator will continue exists in the following decorators. Only make sure the first parameter is request
, and remember to inherit *args
and **kwargs
.
So, to inject a parameter, you can simply write this.
1 | def inject_msg(): |
Then, in the view function, you can get this msg
by adding a parameter.
1 |
|
Or you can inject multiple parameters using a dict
object.
1 | def inject_multiple(): |
Then, the same, you can get these parameters.
1 |
|
That’s it. Now you can gracefully handle parameters in requests! 😁
Epilogue
Although we use decorator to achieve a better request processing, Django itself is not that elegant. It’s time to use a more powerful and promising framework - ASP.NET Core! 💫