def generate_fk_class(name, retrieve_func, limit_to_model=None):
    class CustomForeignKey(ForeignKey):
        def __init__(self, *args, **kwargs):
            if limit_to_model:
                args = (limit_to_model,) + args
            super(CustomForeignKey, self).__init__(*args, **kwargs)

        def contribute_to_class(self, cls, name):
            super(CustomForeignKey, self).contribute_to_class(cls, name)
            setattr(cls, self.name, CachedReverseSingleRelatedObjectDescriptor(self))

        def south_field_triple(self):
            from south.modelsinspector import introspector
            args, kwargs = introspector(self)
            return ('django.db.models.fields.related.ForeignKey', args, kwargs)

    class CachedReverseSingleRelatedObjectDescriptor(ReverseSingleRelatedObjectDescriptor):
        def __get__(self, instance, instance_type=None):
            if instance is None:
                raise AttributeError, "%s must be accessed via instance" % self.field.name
            cache_name = self.field.get_cache_name()
            try:
                return getattr(instance, cache_name)
            except AttributeError:
                val = getattr(instance, self.field.attname)
                if val is None:
                    # If NULL is an allowed value, return it.
                    if self.field.null:
                        return None
                    raise self.field.rel.to.DoesNotExist
                rel_obj = retrieve_func(self.field.rel.to, val)
                setattr(instance, cache_name, rel_obj)
                return rel_obj

    CustomForeignKey.__name__ = name
    return CustomForeignKey
dataset/ETHPy150Open ella/ella/ella/core/cache/fields.py/generate_fk_class/original