为什么我的中间件在注销时没有设置请求属性?

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')