如何在Django中重定向来自中间件的URL?

hts6caw3  于 2023-06-25  发布在  Go
关注(0)|答案(2)|浏览(140)

如何从中间件重定向URL?
无限循环问题。
如果注册尚未完成,我打算将用户重定向到客户端注册URL。

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
qgelzfjb

qgelzfjb1#

每一个对服务器的请求都要经过中间件。因此,当您转到confirm页面时,请求再次通过中间件。因此,最好在这里设置一些条件,以便忽略confirm url。你可以这样尝试:

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
svujldwt

svujldwt2#

更新

尽管遭到了反对,但我仍然不建议在“如果没有注册完成则重定向”的特定用例中使用中间件。
只对应用程序中的每个URL执行该逻辑是一个坏主意。即使用户不需要注册,例如,像这样的页面:“关于我们”、“问答”、“首页”等...
更糟糕的是,考虑到该逻辑涉及数据库查询
这是一个更好的解决方案(即使不是OP特别要求的,本着这样的精神,我有义务分享它),创建一个装饰器(就像login_required的装饰器一样),用于您想要确保用户完成注册的视图中。

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

现在实现你想要的就像装饰一样简单只是你需要的视图,用户注册了才能使用

@registration_required
def my_view(request):
    # Your view code here

你应该使用一个类似于login_required的装饰器,更多细节请参见Django authentication system
示例:

from django.contrib.auth.decorators import login_required

@login_required(login_url="/your/login/view/url/")
def my_view(request):
    ...

根据docs,尽量避免使用中间件进行任何类型的重定向。
中间件是Django的请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变Django的输入或输出。
换句话说,中间件是用来处理请求和响应的,如果你重定向到任何视图,你将(潜在地)递归地触发你的中间件。
另一方面...
将来,您可能希望添加一个可以被匿名用户访问的视图,这个中间件将是一个问题…

相关问题