<NME> models.py
<BEF> import logging
import sys

import collections

from django.db import models
from django.utils.translation import ugettext_lazy as _

from . import geocode
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from . import geocode
from .conf import settings
from .utils import importpath

logger = logging.getLogger(__name__)


class AddressManager(models.Manager):
    def for_address(self, address):
        obj, created = self.get_or_create(address=address)

        if timezone.now() > obj.expiry() and not created:
            obj.save()  # trigger fetching once again

        return obj


class Address(models.Model):

    address = models.CharField(_("address"), max_length=255, unique=True)

        return None

    
class Address(models.Model):

    address = models.CharField(_('address'), max_length=255, unique=True)

    timestamp = models.DateTimeField(auto_now=True)

    objects = AddressManager()

    class Meta:
        verbose_name = _("EasyMaps Address")
        verbose_name_plural = _("Address Geocoding Cache")

    def __str__(self):
        return self.address

    def expiry(self, *args, **kwargs):
        verbose_name = _("EasyMaps Address")
        verbose_name_plural = _("Address Geocoding Cache")

    def __unicode__(self):
        return self.address

    def save(self, *args, **kwargs):
        if func is not None:
            if not isinstance(func, Callable):
                func = importpath(func)

        try:
            self.computed_address, (
                self.latitude,
                self.longitude,
            ) = func(self.address)
        except geocode.Error as e:
            self.computed_address = self.latitude = self.longitude = None  # shit happens

            try:
                logger.error(e)
            except Exception:
                logger.error("Geocoding error for address '%s'", address)

            self.exception = f"{sys.exc_info()[0].__name__}: {sys.exc_info()[1]}"

    def has_exception(self):
        return bool(self.exception)

    has_exception.short_description = _("has exception?")
    has_exception.boolean = True

    def save(self, *args, **kwargs):
        if bool(self.computed_address) is False:  # just in case
            self.longitude = self.latitude = None

        if (self.longitude is None) or (self.latitude is None):
            self.fetch()

        super().save(*args, **kwargs)

<MSG> fix backward compatibility with python 2
<DFF> @@ -4,6 +4,7 @@ import logging
 import collections
 
 from django.db import models
+from django.utils.encoding import python_2_unicode_compatible
 from django.utils.translation import ugettext_lazy as _
 
 from . import geocode
@@ -34,7 +35,8 @@ class AddressManager(models.Manager):
 
         return None
 
-    
+
+@python_2_unicode_compatible  
 class Address(models.Model):
 
     address = models.CharField(_('address'), max_length=255, unique=True)
@@ -54,7 +56,7 @@ class Address(models.Model):
         verbose_name = _("EasyMaps Address")
         verbose_name_plural = _("Address Geocoding Cache")
 
-    def __unicode__(self):
+    def __str__(self):
         return self.address
 
     def save(self, *args, **kwargs):

fix backward compatibility with python 2