有条件地在Django中应用login_required装饰器 [英] Conditionally apply login_required decorator in Django
问题描述
我在 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 $ c的一部分$ c>:
@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屋!