Reputation: 3072
How to redirect url from middleware?
Infinite loop problem.
I intend to redirect the user to a client registration url if the registration has not yet been completed.
def check_user_active(get_response):
def middleware(request):
response = get_response(request)
try:
print(Cliente.objects.get(usuario_id=request.user.id))
except Cliente.DoesNotExist:
return redirect('confirm')
return response
return middleware
Upvotes: 7
Views: 10283
Reputation: 14360
Despite the downvotes, I still do not recommend using middleware for the specific use case of "redirecting if no registration is complete".
It is a bad idea just to execute that logic for every URL in your application. Even if the user does not need registration, for instance, pages like: "About US", "Q&A", "Home", etc ...
Even worst, taking into account that logic involves a database query!
It is a better solution (even if not what the OP is specifically asking for, in the spirit of SO I am obligated to share it) to create a decorator (just like the one for login_required
) to be used in the views you want to ensure the user has finished the registration.
def registration_completed(user):
# Implement your logic to check if registration is completed for the user.
# This can be done by checking a specific field or condition in the user model
# For example, if there is a "registration_completed" field in the User model.
# I will use in the meantime the exact same logic you have in your code.
try:
Cliente.objects.get(usuario_id=request.user.id)
except Cliente.DoesNotExists:
return False
return True
def registration_required(func):
@wraps(func)
def wrapper(request, *args, **kwargs):
if not registration_completed(request.user):
return redirect('registration_completion') # Redirect to registration completion page if registration is not complete
return func(request, *args, **kwargs)
return wrapper
Now achieving what you want is as easy as decorating just the views that you need the user is registered for being able to use:
@registration_required
def my_view(request):
# Your view code here
You should be using a login_required
like decorator see Django authentication system for more detail.
Example:
from django.contrib.auth.decorators import login_required
@login_required(login_url="/your/login/view/url/")
def my_view(request):
...
Avoid using middlewares for any kind of redirection always you can, according to the docs
Middleware is a framework of hooks into Django’s request/response processing. It’s a light, low-level “plugin” system for globally altering Django’s input or output.
In other words, middlewares are there for processing request and responses, if you redirect to any view, you will (potentially) recursively trigger your middleware.
In the future, you might want to add a view that can be visited by anonymous users, this middleware will be a problem ...
Upvotes: 2
Reputation: 51938
Every request to server goes through Middleware. Hence, when you are going to confirm
page, the request goes through middleware again. So its better put some condition here so that it ignores confirm
url. You can try like this:
def check_user_active(get_response):
def middleware(request):
response = get_response(request)
if not request.path == "confirm":
try:
print(Cliente.objects.get(usuario_id=request.user.id))
except Cliente.DoesNotExist:
return redirect('confirm')
return response
return middleware
Upvotes: 9