• Django获取用户请求头部信息


    摘要

    在我们的Django开发中,有时候会需要用到用户请求头部信息。列举几个简单的例子:

    • 获取用户客户端类型HTTP_USER_AGENT
    • 获取用户的出口IPREMOTE_ADDR
    • 获取用户HTTP方式REQUEST_METHOD

    但是如何在Django中获取这些信息呢?

    从请求入手
    1. Django的请求生命周期

    • 用户发出请求,浏览器封装请求头和请求体发给服务端
    • 请求经过Django中的wsgi,到达url关系映射表进行匹配
    • 只要匹配上其中一条匹配规则就执行对应的视图函数
    • 视图函数根据客户端的请求做相应的处理,并将处理结果(字符串)经由模板加工渲染返回给用户
    • 用户浏览器进行渲染后呈现给用户

    2. request里面到底是什么

    我们在某一个视图函数中打印这个request

    def index(request):
        print(type(request),request)
    

    得到输出如下

    <class 'django.core.handlers.wsgi.WSGIRequest'> <WSGIRequest: GET '/index/'>
    

    可见request是一个类WSGIRequest的对象,这个类在django.core.handlers.wsgi中.

    去查看这个类,如下:

    
    class WSGIRequest(http.HttpRequest):
        def __init__(self, environ):
            script_name = get_script_name(environ)
            path_info = get_path_info(environ)
            if not path_info:
                # Sometimes PATH_INFO exists, but is empty (e.g. accessing
                # the SCRIPT_NAME URL without a trailing slash). We really need to
                # operate as if they'd requested '/'. Not amazingly nice to force
                # the path like this, but should be harmless.
                path_info = '/'
            self.environ = environ
            self.path_info = path_info
            # be careful to only replace the first slash in the path because of
            # http://test/something and http://test//something being different as
            # stated in http://www.ietf.org/rfc/rfc2396.txt
            self.path = '%s/%s' % (script_name.rstrip('/'),
                                   path_info.replace('/', '', 1))
            self.META = environ
            self.META['PATH_INFO'] = path_info
            self.META['SCRIPT_NAME'] = script_name
            self.method = environ['REQUEST_METHOD'].upper()
            self.content_type, self.content_params = cgi.parse_header(environ.get('CONTENT_TYPE', ''))
            if 'charset' in self.content_params:
                try:
                    codecs.lookup(self.content_params['charset'])
                except LookupError:
                    pass
                else:
                    self.encoding = self.content_params['charset']
            self._post_parse_error = False
            try:
                content_length = int(environ.get('CONTENT_LENGTH'))
            except (ValueError, TypeError):
                content_length = 0
            self._stream = LimitedStream(self.environ['wsgi.input'], content_length)
            self._read_started = False
            self.resolver_match = None
    ....
    

    可以看到类中封装了一个属性:

    • self.environ
    • self.path_info
    • self.method
    • self.path
    • ...

    我们依次打印出来这些信息看看:

    
    environ {'PATH': '/Users/qiumeng/.pyenv/versions/3.6.2/bin:/usr/local/Cellar/pyenv/1.1.3/libexec:/Users/qiumeng/.pyenv/shims:/Users/qiumeng/.pyenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Applications/Wireshark.app/Contents/MacOS:/Users/qiumeng/GoLang/bin:/usr/local/Cellar/go/1.8.3/libexec/bin', 'PYENV_SHELL': 'bash', 'DISPLAY': '/private/tmp/com.apple.launchd.5ODiXCCeal/org.macosforge.xquartz:0', 'LOGNAME': 'qiumeng', 'PYENV_VERSION': '3.6.2', 'XPC_SERVICE_NAME': 'com.jetbrains.pycharm.8256', 'PWD': '/Users/qiumeng/PycharmProjects/day21', 'PYCHARM_HOSTED': '1', 'PYTHONPATH': '/Users/qiumeng/PycharmProjects/day21', 'SHELL': '/bin/bash', 'PYTHONIOENCODING': 'UTF-8', 'PYENV_DIR': '/Applications/PyCharm.app/Contents/bin', 'PYENV_ROOT': '/Users/qiumeng/.pyenv', 'GOPATH': '/Users/qiumeng/GoLang', 'USER': 'qiumeng', 'GOROOT': '/usr/local/Cellar/go/1.8.3/libexec', 'TMPDIR': '/var/folders/k5/9fcwbxhn1_d_x3lxvs868m6c0000gn/T/', 'PYENV_HOOK_PATH': '/Users/qiumeng/.pyenv/pyenv.d:/usr/local/Cellar/pyenv/1.1.3/pyenv.d:/usr/local/etc/pyenv.d:/etc/pyenv.d:/usr/lib/pyenv/hooks', 'SSH_AUTH_SOCK': '/private/tmp/com.apple.launchd.kT7ERQ3lJ4/Listeners', 'DJANGO_SETTINGS_MODULE': 'day21.settings', 'XPC_FLAGS': '0x0', 'PYTHONUNBUFFERED': '1', '__CF_USER_TEXT_ENCODING': '0x1F5:0x19:0x34', 'Apple_PubSub_Socket_Render': '/private/tmp/com.apple.launchd.nEfmDxko1b/Render', 'LC_CTYPE': 'zh_CN.UTF-8', 'HOME': '/Users/qiumeng', 'TZ': 'UTC', 'RUN_MAIN': 'true', 'SERVER_NAME': '1.0.0.127.in-addr.arpa', 'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PORT': '8000', 'REMOTE_HOST': '', 'CONTENT_LENGTH': '', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/index/', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '127.0.0.1:8000', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_CACHE_CONTROL': 'max-age=0', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'HTTP_COOKIE': 'csrftoken=Ne1RJ3duPUV5mFJysr9r48fgEZCaJY75RFsh6ujbELqQYYzxOynhoLSVT3GnUblx', 'wsgi.input': <_io.BufferedReader name=4>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>}
    
    path_info /index/
    method GET
    path /index/
    
    
    3. environ属性

    从上面的environ中我们看到,我们想要的任何存在的请求头信息是在environ
    这个属性中的,我们把它一一列举一下:

    def index(request):
        print(type(request.environ))
        for k,v in request.environ.items():
            print(k,v)
    

    结果如下:

    PATH /Users/qiumeng/.pyenv/versions/3.6.2/bin:/usr/local/Cellar/pyenv/1.1.3/libexec:/Users/qiumeng/.pyenv/shims:/Users/qiumeng/.pyenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Applications/Wireshark.app/Contents/MacOS:/Users/qiumeng/GoLang/bin:/usr/local/Cellar/go/1.8.3/libexec/bin
    PYENV_SHELL bash
    DISPLAY /private/tmp/com.apple.launchd.5ODiXCCeal/org.macosforge.xquartz:0
    LOGNAME qiumeng
    PYENV_VERSION 3.6.2
    XPC_SERVICE_NAME com.jetbrains.pycharm.8256
    PWD /Users/qiumeng/PycharmProjects/day21
    PYCHARM_HOSTED 1
    PYTHONPATH /Users/qiumeng/PycharmProjects/day21
    SHELL /bin/bash
    PYTHONIOENCODING UTF-8
    PYENV_DIR /Applications/PyCharm.app/Contents/bin
    PYENV_ROOT /Users/qiumeng/.pyenv
    GOPATH /Users/qiumeng/GoLang
    USER qiumeng
    GOROOT /usr/local/Cellar/go/1.8.3/libexec
    TMPDIR /var/folders/k5/9fcwbxhn1_d_x3lxvs868m6c0000gn/T/
    PYENV_HOOK_PATH /Users/qiumeng/.pyenv/pyenv.d:/usr/local/Cellar/pyenv/1.1.3/pyenv.d:/usr/local/etc/pyenv.d:/etc/pyenv.d:/usr/lib/pyenv/hooks
    SSH_AUTH_SOCK /private/tmp/com.apple.launchd.kT7ERQ3lJ4/Listeners
    DJANGO_SETTINGS_MODULE day21.settings
    XPC_FLAGS 0x0
    PYTHONUNBUFFERED 1
    __CF_USER_TEXT_ENCODING 0x1F5:0x19:0x34
    Apple_PubSub_Socket_Render /private/tmp/com.apple.launchd.nEfmDxko1b/Render
    LC_CTYPE zh_CN.UTF-8
    HOME /Users/qiumeng
    TZ UTC
    RUN_MAIN true
    SERVER_NAME 1.0.0.127.in-addr.arpa
    GATEWAY_INTERFACE CGI/1.1
    SERVER_PORT 8000
    REMOTE_HOST 
    CONTENT_LENGTH 
    SCRIPT_NAME 
    SERVER_PROTOCOL HTTP/1.1
    SERVER_SOFTWARE WSGIServer/0.2
    REQUEST_METHOD GET
    PATH_INFO /index/
    QUERY_STRING 
    REMOTE_ADDR 127.0.0.1
    CONTENT_TYPE text/plain
    HTTP_HOST 127.0.0.1:8000
    HTTP_CONNECTION keep-alive
    HTTP_CACHE_CONTROL max-age=0
    HTTP_USER_AGENT Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36
    HTTP_UPGRADE_INSECURE_REQUESTS 1
    HTTP_ACCEPT text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    HTTP_ACCEPT_ENCODING gzip, deflate, br
    HTTP_ACCEPT_LANGUAGE zh-CN,zh;q=0.9
    HTTP_COOKIE csrftoken=Ne1RJ3duPUV5mFJysr9r48fgEZCaJY75RFsh6ujbELqQYYzxOynhoLSVT3GnUblx
    wsgi.input <_io.BufferedReader name=5>
    wsgi.errors <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>
    wsgi.version (1, 0)
    wsgi.run_once False
    wsgi.url_scheme http
    wsgi.multithread True
    wsgi.multiprocess False
    wsgi.file_wrapper <class 'wsgiref.util.FileWrapper'>
    
  • 相关阅读:
    代码优化:尽量减少对变量的重复计算
    Easy code数据库类型NUMBER(20),没有找到映射关系
    Apache JMeter的下载和安装
    启动报错:Error Running cant find catalina.jar
    创建自定义配置节
    Word转Chm 在线转换应用
    silverlight概述
    布局
    case of silverlight
    关于SilverLight打印(二)
  • 原文地址:https://www.cnblogs.com/forsaken627/p/12521980.html
Copyright © 2020-2023  润新知