GeoIP country lookup change in Django 5.1

Earlier this week, I tried to add 5.1 support to a 3rd party package django-user-sessions and stumbled upon a change in behaviour.

Here is a test which passes in Django 5.0:

class TestGeoIP(TestCase):
    def test_geoip(self):
        geoip = GeoIP2()
        result = geoip.country('8.8.8.8')
        self.assertEqual(result, {'country_code': 'US', 'country_name': 'United States'})

This fails in Django 5.1 and raises an exception geoip2.errors.AddressNotFoundError: The address 8.8.8.8 is not in the database.

It seems somewhat related to a change in the release notes:

GeoIP2 no longer opens both city and country databases when a directory path is provided, preferring the city database, if it is available. The country database is a subset of the city database and both are not typically needed. If you require use of the country database when in the same directory as the city database, explicitly pass the country database path to the constructor.

I’m thinking that because on 5.1, the GeoIP2 instance is initialized with the city database, while on 5.0, the instance has a reference to both the city and country file.

Few questions:

  1. Is it an expected behaviour with 5.1 or should it be reported as a bug?
  2. If it’s intended, how are we supposed to adjust the code to work? Should we update the documentation to make it clearer?

I’m not very familiar with GeoIP, so apologies if it’s a basic question.

@ngnpope did the refactoring, maybe he’ll be able to give you some hints.

1 Like

Hi. So, yes, this was an intentional change. The country database is a subset of the city database, so opening and reading both doesn’t make sense. Before Django 5.1, if one database is outdated, you might get different results depending on the method called to fetch the data which is far from ideal.

It seems that the issue you are having is due to django-user-sessions generating it’s own database files. Ironically this highlights exactly the problem this change was intended to prevent because the fake data for each of the city and country files is inconsistent - they each have a single, different IP.

You could simply update the generation to be consistent, but I’d recommend just doing what we now do in Django and copy in the test files provided by MaxMind. See here for the test files and here for the GeoIP2 tests in Django.

1 Like

Makes sense! Thanks for the help.