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

时间:2015-05-17 09:54:08

标签: python django django-middleware

我有一段代码在用户通过我的android子域访问时设置了一个请求属性(在下面显示为home.devices.py的一部分。)然后在base.html中选中并且曾经包含我的android-navbar.html。除了logout.html之外,这在我的所有页面上都能正常工作。无论用户是否登录都是如此。

正如您在下面base.html的模板片段中看到的那样,我将UA和子域的值输出到页面,这对所有其他页面都能正常工作,但在注销页面上不返回任何内容。

我还通过添加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

1 个答案:

答案 0 :(得分:1)

渲染模板时,您没有使用RequestContext,因此请求变量不存在。请改用render快捷方式。

 return render(request, 'registration/logout.html')