How do I get user IP address in Django?
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------
Music by Eric Matyas
https://www.soundimage.org
Track title: Ocean Floor
--
Chapters
00:00 How Do I Get User Ip Address In Django?
00:29 Accepted Answer Score 584
01:14 Answer 2 Score 265
02:22 Answer 3 Score 95
02:57 Answer 4 Score 29
03:19 Answer 5 Score 19
03:58 Thank you
--
Full question
https://stackoverflow.com/questions/4581...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #django
#avk47
ACCEPTED ANSWER
Score 589
def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip
Make sure you have reverse proxy (if any) configured correctly (e.g. mod_rpaf installed for Apache).
Note: the above uses the first item in X-Forwarded-For, but you might want to use the last item (e.g., in the case of Heroku: Get client's real IP address on Heroku)
And then just pass the request as argument to it;
get_client_ip(request)
ANSWER 2
Score 268
You can use django-ipware which supports Python 2 & 3 and handles IPv4 & IPv6.
Install:
pip install django-ipware
Simple Usage:
# In a view or a middleware where the `request` object is available
from ipware import get_client_ip
ip, is_routable = get_client_ip(request)
if ip is None:
    # Unable to get the client's IP address
else:
    # We got the client's IP address
    if is_routable:
        # The client's IP address is publicly routable on the Internet
    else:
        # The client's IP address is private
# Order of precedence is (Public, Private, Loopback, None)
Advanced Usage:
Custom Header - Custom request header for ipware to look at:
i, r = get_client_ip(request, request_header_order=['X_FORWARDED_FOR']) i, r = get_client_ip(request, request_header_order=['X_FORWARDED_FOR', 'REMOTE_ADDR'])Proxy Count - Django server is behind a fixed number of proxies:
i, r = get_client_ip(request, proxy_count=1)Trusted Proxies - Django server is behind one or more known & trusted proxies:
i, r = get_client_ip(request, proxy_trusted_ips=('177.2.2.2')) # For multiple proxies, simply add them to the list i, r = get_client_ip(request, proxy_trusted_ips=('177.2.2.2', '177.3.3.3')) # For proxies with fixed sub-domain and dynamic IP addresses, use partial pattern i, r = get_client_ip(request, proxy_trusted_ips=('177.2.', '177.3.'))
Note: read this notice.
ANSWER 3
Score 95
Alexander's answer is great, but lacks the handling of proxies that sometimes return multiple IP's in the HTTP_X_FORWARDED_FOR header.
The real IP is usually at the end of the list, as explained here: http://en.wikipedia.org/wiki/X-Forwarded-For
The solution is a simple modification of Alexander's code:
def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[-1].strip()
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip
ANSWER 4
Score 19
I would like to suggest an improvement to yanchenko's answer.
Instead of taking the first ip in the X_FORWARDED_FOR list, I take the first one which in not a known internal ip, as some routers don't respect the protocol, and you can see internal ips as the first value of the list.
PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', )
def get_client_ip(request):
    """get the client ip from the request
    """
    remote_address = request.META.get('REMOTE_ADDR')
    # set the default value of the ip to be the REMOTE_ADDR if available
    # else None
    ip = remote_address
    # try to get the first non-proxy ip (not a private ip) from the
    # HTTP_X_FORWARDED_FOR
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        proxies = x_forwarded_for.split(',')
        # remove the private ips from the beginning
        while (len(proxies) > 0 and
                proxies[0].startswith(PRIVATE_IPS_PREFIX)):
            proxies.pop(0)
        # take the first ip which is not a private one (of a proxy)
        if len(proxies) > 0:
            ip = proxies[0]
    return ip
I hope this helps fellow Googlers who have the same problem.