I stumbled on exactly the same problem, luckily, I've fixed it.
The original solution (the one you used) comes from this question, my solution is based on it:
class ForeignKeyLinksMetaclass(MediaDefiningClass):
def __new__(cls, name, bases, attrs):
new_class = super(
ForeignKeyLinksMetaclass, cls).__new__(cls, name, bases, attrs)
def foreign_key_link(instance, field):
target = getattr(instance, field)
return u'<a href="../../%s/%s/%d/">%s</a>' % (
target._meta.app_label, target._meta.module_name,
target.id, unicode(target)
)
for name in new_class.list_display:
if name[:8] == 'link_to_':
method = partial(foreign_key_link, field=name[8:])
method.__name__ = name[8:]
method.allow_tags = True
setattr(new_class, name, method)
return new_class
Well, the only thing you need is to replace the original ModelAdminWithForeignKeyLinksMetaclass with the one above.
However, it's not the end. The most interesting part is why the original solution causes problems. The answer to this question lies here (line 31) and here (line 244).
When DEBUG is on Django tries to validate all registered ModelAdmins (first link). There cls is a class SomeAdmin (i.e. an instance of its metaclass). When hasattr is called, python tries to find an attribute field in class SomeAdmin or in one of its super classes. Since it is impossible, __getattr__ of its class (i.e. SomeAdmin's metaclass) is called, where a new method is added to class SomeAdmin. Hence, when it comes to rendering the interface, SomeAdmin is already patched and Django is able to find the required field (second link).
When DEBUG is False, Django skips the validation. When the interface is rendered Django tries to find a field (again, second link), but this time SomeAdmin is not patched, moreover model_admin is not class SomeAdmin, it is its instance. Thus, trying to find an attribute name in model_admin, python is unable to do this, neither it is able to find it in its class (SomeAdmin) as well as in any of its super classes, so an exception is raised.