问题:
我正在尝试访问中间件层中视图示例的一个属性。
例如,给定一个像这样的基于类的视图:
# views.py
class MyView(View):
my_attribute = 'something'
我希望能够在中间件中处理my_attribute
,方法如下:
# middleware.py
def process_view(self, request, view_func, view_args, view_kwargs):
my_attribute = request.view.my_attribute
当然,这是不起作用的,因为Django没有通过request对象公开视图示例。有没有办法做到这一点?
谢谢!
第一次尝试:
我最初认为process_view()
方法可能是完成此任务的好地方。不幸的是,它接收的view_func
参数包含一个函数--MyView.as_view()
的输出--而不是视图示例本身。Django文档:
process_view(self,request,view_func,view_args,view_kwargs)
view_func是Django将要使用的Python函数。(它是实际的函数对象,而不是字符串形式的函数名。)...
第二次尝试:
视图示例的句柄在process_template_response()
方法中可用,但它非常笨拙,而且无论如何,我希望能够在中间件堆栈的早期使用my_attribute
。但这确实有效:
def process_template_response(self, request, response):
my_attribute = response.context_data['view'].my_attribute
4条答案
按热度按时间w1e3prcc1#
没有内置的方法可以做到这一点,但这里有一个由django-users邮件列表上的一位好心的用户给我的解决方案。我在这里重新发布他的建议,以防其他人试图做同样的事情。
这在以下情况下很有用:
1.您希望在中间件中识别当前视图的属性并相应地执行处理,并且;
1.出于各种原因,您不希望使用mixin或装饰器来实现类似的结果。
这将检查传递给
process_view()
中间件钩子的view_func
对象,并确定和导入适当的视图类。然后你的
get_class()
定义:7d7tgy0s2#
使用装饰器,有相当多的方法来实现期望的行为。
1.如果您只想标记一个类,让中间件做一些事情
2.如果您想将视图中不需要的数据传递给中间件
3.如果需要向中间件暴露一些视图属性
4.如果要将基于类的整个视图公开给中间件
m4pnthwp3#
另一种解决方案是创建一个新的View类:
并在基于类的视图中使用它:
然后在中间件中执行以下操作:
这个方法在
Django REST Framework
(https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/views。py#L94-L104)34gzjxbg4#
如果它依赖于视图,那么它应该是该视图的混合。如果你正在做一些类似于依赖于活动视图的菜单的事情,我会对当前URL名称进行反向查找:
查看前面关于使用当前URL的URL名称查找的答案