为什么我的中间件在注销时没有设置请求属性?
Why is my middleware not setting request attributes on logout?
我有一段代码,当用户通过我的 android
子域访问时设置请求属性(如下所示,作为 home.devices.py
的一部分。然后在 [=16] 中获取=] 并用于包括我的 android-navbar.html
。除了 logout.html
之外,这在我的所有页面上都可以正常工作。无论用户是否登录都是这种情况。
正如您在下方 base.html
的模板片段中看到的,我将 UA 和子域的值输出到页面,这对所有其他页面都有效,但 returns注销页面。
我还通过添加 assert False
语句进行了检查,如果我的 request.subdomain
属性未设置为 android
,该语句就会触发。但是它没有被触发,所以很明显中间件在工作,但是我的注销页面没有访问子域和 UA 变量。
为什么会发生这种情况,我该如何解决?
可能相关的代码位:
app.views
def logout(request):
auth.logout(request)
if not request.subdomain == 'android':
assert False
return render_to_response('registration/logout.html')
app.settings
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'home.device.MobileMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
base.html 模板片段
...
{% if request.subdomain == 'android' %}
{% include 'home/android-navbar.html' %}
{% else %}
{% include 'home/navbar.html' %}
{% endif %}
{% endblock %}
</div>
<div>UA is: {{ request.ua_full }}</div>
<div>Subdomain is: {{ request.subdomain }}</div>
....
home.devices.py
# list of mobile User Agents
mobile_uas = [
'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',
'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',
'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',
'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',
'newt','noki','oper','palm','pana','pant','phil','play','port','prox',
'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',
'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',
'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',
'wapr','webc','winw','winw','xda','xda-'
]
mobile_ua_hints = [ 'SymbianOS', 'Opera Mini', 'iPhone', 'Mobile Safari' ]
def is_mobile(request):
''' Super simple device detection, returns True for mobile devices '''
mobile_browser = False
ua = request.META['HTTP_USER_AGENT'].lower()[0:4]
ua_full = request.META['HTTP_USER_AGENT']
if (ua in mobile_uas):
mobile_browser = True
else:
for hint in mobile_ua_hints:
if request.META['HTTP_USER_AGENT'].find(hint) > 0:
mobile_browser = True
return mobile_browser
def get_ua(request):
''' Return the name of the user agent '''
ua_full = request.META['HTTP_USER_AGENT']
return ua_full
def get_subdomain(request):
subdomain = request.META['HTTP_HOST'].split('.')[0]
return subdomain
class MobileMiddleware(object):
def __init__(self):
pass
def process_request(self, request):
request.mobile = is_mobile(request)
request.ua_full = get_ua(request)
request.subdomain = get_subdomain(request)
return
您在呈现模板时没有使用 RequestContext,因此请求变量不存在。请改用 render
快捷方式。
return render(request, 'registration/logout.html')
我有一段代码,当用户通过我的 android
子域访问时设置请求属性(如下所示,作为 home.devices.py
的一部分。然后在 [=16] 中获取=] 并用于包括我的 android-navbar.html
。除了 logout.html
之外,这在我的所有页面上都可以正常工作。无论用户是否登录都是这种情况。
正如您在下方 base.html
的模板片段中看到的,我将 UA 和子域的值输出到页面,这对所有其他页面都有效,但 returns注销页面。
我还通过添加 assert False
语句进行了检查,如果我的 request.subdomain
属性未设置为 android
,该语句就会触发。但是它没有被触发,所以很明显中间件在工作,但是我的注销页面没有访问子域和 UA 变量。
为什么会发生这种情况,我该如何解决?
可能相关的代码位:
app.views
def logout(request):
auth.logout(request)
if not request.subdomain == 'android':
assert False
return render_to_response('registration/logout.html')
app.settings
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'home.device.MobileMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
base.html 模板片段
...
{% if request.subdomain == 'android' %}
{% include 'home/android-navbar.html' %}
{% else %}
{% include 'home/navbar.html' %}
{% endif %}
{% endblock %}
</div>
<div>UA is: {{ request.ua_full }}</div>
<div>Subdomain is: {{ request.subdomain }}</div>
....
home.devices.py
# list of mobile User Agents
mobile_uas = [
'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',
'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',
'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',
'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',
'newt','noki','oper','palm','pana','pant','phil','play','port','prox',
'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',
'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',
'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',
'wapr','webc','winw','winw','xda','xda-'
]
mobile_ua_hints = [ 'SymbianOS', 'Opera Mini', 'iPhone', 'Mobile Safari' ]
def is_mobile(request):
''' Super simple device detection, returns True for mobile devices '''
mobile_browser = False
ua = request.META['HTTP_USER_AGENT'].lower()[0:4]
ua_full = request.META['HTTP_USER_AGENT']
if (ua in mobile_uas):
mobile_browser = True
else:
for hint in mobile_ua_hints:
if request.META['HTTP_USER_AGENT'].find(hint) > 0:
mobile_browser = True
return mobile_browser
def get_ua(request):
''' Return the name of the user agent '''
ua_full = request.META['HTTP_USER_AGENT']
return ua_full
def get_subdomain(request):
subdomain = request.META['HTTP_HOST'].split('.')[0]
return subdomain
class MobileMiddleware(object):
def __init__(self):
pass
def process_request(self, request):
request.mobile = is_mobile(request)
request.ua_full = get_ua(request)
request.subdomain = get_subdomain(request)
return
您在呈现模板时没有使用 RequestContext,因此请求变量不存在。请改用 render
快捷方式。
return render(request, 'registration/logout.html')