Forums

Getting User's Location in Django (am using GeoIP)

I just need to know what country my users are calling from. The quickest (read: laziest) solution I found was this one:

https://docs.djangoproject.com/en/dev/ref/contrib/gis/geoip/

Works fine on my home machine - I can whack in an IP and it spits out the country. Can't be that hard to get the user's IP from django, so I thought I was good to go.

Unfortunately the PythonAnywhere servers disagree - the django geoip module isn't there and, looking a bit closer, I see geoip itself is actually just a wrapper around a C library. What's the PA policy on binaries then, and how should I go about setting this one up?

Unless of course, there's a better, easier recommended way of looking up user location - in which case, what would that be?

I just tried to compile the geoip library on PythonAnywhere and it looks like we're missing something. I'll raise a ticket to get that installed for you.

Thanks Glenn.

But as I said, if anyone knows of a simpler or pure-python solution, I'm all ears.

Have you had a look at this?

Actually, pygeoip looks fine for what I need. Thanks!

Since 2013, have anyone got Django's geoip working fine on Pythonanywhere?

I'm planning to deploy a geolocation feature on my sites and wonder if I need to read more on Django's tool or search some other tools?

We've definitely installed various geoip libraries since 2013, but I don't know whether or not we installed the specific one that's used by Django. Probably best to just try it out!

Thanks! Django did deprecated and updated some stuff to shift to geoip2 since 1.9, so I'll try it this weekend. Not found this on PA's batteries_included, so I'll check it this weekend.

Great! We'd love to hear how you get on.

Hi! Here's update on using geoip in Django as for 2016, in case anyone would wonder.

The good part:

  1. The pygeoip mentioned here seems to work with maxmind databases only.
  2. The Django's built-in geolocation (it's GeoIP2 since 1.9) works with maxmind databases :-). Installation is pretty straightforward. So, no need in pygeoip actually.

The weird part

It works fine in bash, when feeding it with commands like g.country('google.com')

However, my test site deployed on Pythonanywhere always detects the same ip, regardless of providers I use to connect to the site:

  • two local ISPs
  • another one mobile ISP
  • a VPN (ExpressVPN) tunnel through New York to browse the site

... well, in all cases the PA site says ...the ip address is 10.149.68.189...

The code is:

def get_geo_ip(request): """ """ ip = request.META.get('REMOTE_ADDR', '') or request.META.get('HTTP_X_FORWARDER_FOR', '') return ip

I thought changing internet providers would change IPs. How it happens to be the same weird IP? Is it something I misunderstand about IPs or is it a feature of PA?

I solved it: my code did not return real IP, showing me Pythonanywhere's or some other's IP. django-ipware gets real IP in a single line of code. Now both getting IP and GeoIP2 on Django works fines. I hope this will save an hour to others deploying geolocation with Django on PA.

Thanks for the writeup :D Will definitely be saving people hours.

              / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\  
 <<<<<<:>~  <   Yay!           |
               \_________/

Just an extra bit of info for anyone else who hits a similar problem and can't use django-ipware -- the REMOTE_ADDR on PythonAnywhere is the IP address of the loadbalancer associated with your web app. The field to use for the "real" IP address -- which, strictly speaking, is the one that sent data to the loadbalancer, and will normally be the IP address of the user's browser, though of course it may be some intermediate proxy or VPN server -- is X-Real-IP, which Django exposes as HTTP_X_REAL_IP. More info here.

(My guess is that django-ipware has a list of the various kinds of headers that different loadbalancers put the original IP address in -- HTTP_X_FORWARDER_FOR, HTTP_X_REAL_IP, and so on, and tries them all until it finds an IP address.)

can you whitelist geolocation-dp.com

@coder0 -- we're happy to consider a public API for whitelisting if you provide us with official documentation for it.