Django 1.6 OrderedDict保留状态跨请求?或默认启用缓存? [英] Django 1.6 OrderedDict retaining state across requests? or cacheing enabled by default?
问题描述
所有视图都是使用基于类的视图编写的。所有仪表板视图都继承自父混合视图,确保登录用户具有查看他们要查看的对象的权限,并根据用户角色构建仪表板选项卡。
class ParentMixin(object):
pages = OrderedDict([
('General':{'link':build_a_link_for_the_logged_in_user()}) ,
])
def dispatch(self,* args,** kwargs):
#验证登录用户有权查看请求的对象
如果user_passes_test (self.request.user):
self.object = get_users_object_to_view(self.request.user)
def get_context_data(self,** kwargs):
if self.request .is_superuser和self.object.is_demo:
self.pages ['Superuser'] = {'link':build_link()}
context = super(parent_get_context_data)
上下文['pages' ] = self.pages
然后在基本模板中,所有仪表板视图继承,显示动态选项卡/链接:
{%for page_name,page_data in pages.items%}
{%if page_data.is_current%}
< a href ={{page_data.link}}class =current>
{%else%}
< a href ={{page_data.link}}>
{%endif%}
{{page_name}}
< / a>
{%endfor%}
我的问题: p>
今天早上,我注意到如果我有一个请求的演示对象,然后点击链接查看不同的对象仪表板,最后一个对象 Superuser
链接仍会显示在页面字典!!!!我在视图中放入了debug语句。该视图将认识到我是超级用户,而 object.is_demo
为False。所以条件不会添加超级用户
链接到 self.pages
。 但超级用户
链接仍然在 self.pages
中,并且具有我查看的最后一个对象的链接
有谁知道这些数据如何在请求之间持续存在?或者可能会看到我的方法有问题?
我今天早上修复了错误,从 self中删除
超级用户
。在执行条件检查以查看超级用户是否提出请求并且该对象是一个演示之前,页面
如果self.pages中的超级用户:
del(self.pages ['Superuser'])
谢谢,
这样做正是你所说的。您将页面
设置为ParentMixin的类属性,这意味着它也将是您混合到其中的任何视图类的类属性。类属性在进程中的类的所有实例之间共享,并且由于进程持续跨越许多请求,所以数据将持续跨越这些请求。
您应该始终设置属性在 self
,这意味着在一个方法中进行,在这种情况下可能在 get_context_data
内。 Django会尽量保证在基于类的视图中不会共享实例数据,但这不适用于类级数据。
I am using django 1.6.0. I am working on a web app with a client "dashboard". In the client dashboard there are tabs in the header of the base template. The tabs are dynamic and change based on the role/permissions of the user viewing the dashboard.
All the views are written using class based views. All of the dashboard views inherit from a parent mixin view that makes sure the logged in user has permission to view the objects that they requested to view, and that builds the dashboard tabs based on their user role.
class ParentMixin(object):
pages = OrderedDict([
('General': { 'link': build_a_link_for_the_logged_in_user()}),
])
def dispatch(self, *args, **kwargs):
# validate that logged in user has permission to view requested objects
if user_passes_test(self.request.user):
self.object = get_users_object_to_view(self.request.user)
def get_context_data(self, **kwargs):
if self.request.is_superuser and self.object.is_demo:
self.pages['Superuser'] = {'link': build_link()}
context = super(parent_get_context_data)
context['pages'] = self.pages
Then in base template that all dashboard views inherit from, the dynamic tabs/links are displayed:
{% for page_name, page_data in pages.items %}
{% if page_data.is_current %}
<a href="{{ page_data.link }}" class="current">
{% else %}
<a href="{{ page_data.link }}">
{% endif %}
{{ page_name }}
</a>
{% endfor %}
My Question:
This morning, i noticed if I had a requested a demo object, then clicked on a link to view a different objects dashboard, the last objects Superuser
Link would still show up in the pages dictionary!!!! I put in debug statements in the view. The view would recognize that I was a superuser and the object.is_demo
was False. So the conditionaly would not add the Superuser
link to the self.pages
. But the Superuser
link was still in self.pages
and it had the Link from the last object I viewed. This is the only place that self.pages['Superuser']
was being set.
Does anyone know how this data could persist between requests? Or could see something wrong with my approach??
I fixed the bug this morning by removing the Superuser
from self.pages
before doing the conditional check to see if a superuser was making the request and the object was a demo:
if 'Superuser' in self.pages:
del(self.pages['Superuser'])
Thank you,
This is doing exactly what you tell it. You've set pages
to be a class attribute of ParentMixin, which means it will also be a class attribute of any view class you mix it in to. Class attributes are shared across all instances of the class within a process, and since a process lasts across many requests, the data will persist across those requests.
You should always set attributes on self
, which means doing it inside a method, in this case probably inside get_context_data
. Django goes to some lengths to ensure that instance data is not shared in class-based views, but this does not apply to class-level data.
这篇关于Django 1.6 OrderedDict保留状态跨请求?或默认启用缓存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!