有条件地在Django中应用login_required装饰器 [英] Conditionally apply login_required decorator in Django

查看:66
本文介绍了有条件地在Django中应用login_required装饰器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 views.py 中有一组功能,这些功能目前只能由用户访问。我被要求使其可公开访问,目前,我在视图中使用 @login_required 装饰器。有没有一种方法可以根据所提供的对象有条件地应用此修饰器?

I have a set of function in views.py which are currently only user-accessible. I'm asked to make it publicly accessible and currently I am using the @login_required decorator in my views. Is there a way to apply this decorator conditionally based on the object being served?

例如,我的 views.py

@login_required
def details(request, object_id):
    o = get_object_or_404(Model, pk=object_id)

    if o.user_id == request.user.pk:
        return render(request, 'app/details.html')
    else:
        return redirect('app:home')

我想做什么:

if not o.is_public:
    @login_required
def details(request, object_id):
    o = get_object_or_404(Model, pk=object_id)

    if o.user_id == request.user.pk:
        return render(request, 'app/details.html')
    else:
        return redirect('app:home')

当然,代码不会因为(i)这不是有效的Python,并且(ii)我需要先获取该对象,因此可以正常工作。我相信使用Django可能会有一个优雅的解决方案,因为这是Web应用程序中的常见功能,但是我对这些文档都没有用。我想应该将 @login_required 装饰器与另一个装饰器包围在一起,但是我对Python中的装饰器不太熟悉。谢谢您的帮助。

Of course, the code doesn't work since (i) it's not valid Python and (ii) I need to first get the object. I believe there might be an elegant solution using Django as this is quite a common feature in web applications but I've gone through the docs to no avail. I think I should surround the @login_required decorator with another decorator but I'm not too familiar with decorators in Python. Any help is appreciated.

推荐答案

它不能与装饰器一起使用,因为装饰器是在导入时以及在您输入时进行评估和应用的。已经说过,您需要首先根据请求获得对象。

It will not work with a decorator because decorators are evaluated and applied on import time and, as you've said, you need to get the object first, which is based on the request.

由于您已经请求了一种优雅的解决方案,我假设您想要为其创建装饰器,以便可以在多个视图上重用它,那么解决方案是基于类的视图。您可以将所需的行为实现为基于类的视图混合,您可以将其混合到不同的基于类的视图中。这种提高的灵活性是引入基于类的视图的原因之一。

Since you've asked for an elegant solution, and I'm assuming you want to create a decorator for it so you can reuse it on multiple views, then the solution is a class-based view. You can implement the behavior that you want as a class-based view mixin, which you can mix-in to different class-based views. This improved flexibility is one of the reasons class-based views were introduced.

这篇关于有条件地在Django中应用login_required装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆