Если вы используете Django админку, и хоть раз пробовали перевести имя приложения на русский язык, то для вас не станет сюрпризом отсутствие стандартного, предусмотренного разработчиками решения. В сети (в том числе и на хабре) можно найти информацию, посвященную этой проблемы.
Некоторые решения отлично работают, хоть и представляются слишком трудоемкими, другие ломают нативные джанговские тесты. Однако я не нашел ни одного простого решения, которое позволило бы изменить имя приложения в breadcrumbs.
Итак давайте посмотрим на внутренности админки и на то как можно решить нашу проблему.

Всего в джанго 29 шаблонов, использующих breadcrumbs, это легко проверить выполнив из корневого каталога фреймворка:
Поэтому пришлось отказаться от переписывания стандарнтых шаблонов и обратить свое внимание на другие места, в котрых можно переопределить все и сразу.
Таким местом оказался модуль admin.py внутри приложения, потому что через его функцию admin.site.register проходят все модели которые будут отображаться в админке. Так что если обернуть ее в свой декоратор, то можно сразу в одном месте воздействовать на все зарегистрированные модели.
Все казалось просто – перегрузить несколько функций, атрибутов и дело сделано, но подвох оказался в том, что в разных шаблонах по разному определяется app_label. Так, например в app_index.html передается список app_list, у каждого элемента которого есть аттрибут name, в шаблон change_form.html передается сразу app_label. Поэтому в представленном вашему вниманию решении пришлось использовать несколько хаков.
Итак, от слов перейдем к коду:
Осталось только вставить сорцы в admin.py вашего приложения, подставив свои аргументы (native_app_label и app_label) в конструктор класса и запустив main().
Класс string_with_realoaded_title взят отсюда.
Спасибо за внимание.
Некоторые решения отлично работают, хоть и представляются слишком трудоемкими, другие ломают нативные джанговские тесты. Однако я не нашел ни одного простого решения, которое позволило бы изменить имя приложения в breadcrumbs.
Итак давайте посмотрим на внутренности админки и на то как можно решить нашу проблему.

Всего в джанго 29 шаблонов, использующих breadcrumbs, это легко проверить выполнив из корневого каталога фреймворка:
grep -R "{% block breadcrumbs %}" . | nl
Поэтому пришлось отказаться от переписывания стандарнтых шаблонов и обратить свое внимание на другие места, в котрых можно переопределить все и сразу.
Таким местом оказался модуль admin.py внутри приложения, потому что через его функцию admin.site.register проходят все модели которые будут отображаться в админке. Так что если обернуть ее в свой декоратор, то можно сразу в одном месте воздействовать на все зарегистрированные модели.
Все казалось просто – перегрузить несколько функций, атрибутов и дело сделано, но подвох оказался в том, что в разных шаблонах по разному определяется app_label. Так, например в app_index.html передается список app_list, у каждого элемента которого есть аттрибут name, в шаблон change_form.html передается сразу app_label. Поэтому в представленном вашему вниманию решении пришлось использовать несколько хаков.
Итак, от слов перейдем к коду:
from django.db.models.base import ModelBase
from django.core.urlresolvers import resolve
class AppLabelRenamer(object):
''' Переименовывает имя приложения и breadcrumbs в админке. '''
def __init__(self, native_app_label, app_label):
''' self.module служит для отсеивания моделей других приложений. '''
self.native_app_label = native_app_label
self.app_label = app_label
self.module = '.'.join([native_app_label, 'models'])
class string_with_realoaded_title(str):
''' Класс для имени нашего приложения. Перегружает метод title,
что впоследствии приводит к переименованию приложения.
Спасибо Ionel Maries Cristian '''
def __new__(cls, value, title):
instance = str.__new__(cls, value)
instance._title = title
return instance
def title(self):
return self._title
__copy__ = lambda self: self
__deepcopy__ = lambda self, memodict: self
def rename_app_label(self, f):
''' Изменяет имя приложения и breadcrumbs '''
app_label = self.app_label
def rename_breadcrumbs(f):
def wrap(self, *args, **kwargs):
extra_context = kwargs.get('extra_context', {})
extra_context['app_label'] = app_label
kwargs['extra_context'] = extra_context
return f(self, *args, **kwargs)
return wrap
def wrap(model_or_iterable, admin_class=None, **option):
''' '''
if isinstance(model_or_iterable, ModelBase):
model_or_iterable = [model_or_iterable]
for model in model_or_iterable:
if model.__module__ != self.module:
continue
if admin_class is None:
admin_class = type(model.__name__+'Admin',
(admin.ModelAdmin,), {})
admin_class.add_view = rename_breadcrumbs(admin_class.add_view)
admin_class.change_view = rename_breadcrumbs(admin_class.change_view)
admin_class.changelist_view = rename_breadcrumbs(admin_class.changelist_view)
model._meta.app_label = self.string_with_realoaded_title(
self.native_app_label,
self.app_label)
return f(model, admin_class, **option)
return wrap
def rename_app_index(self, f):
''' Изменяет breadcrumb для имени приложения в app_index.html
Здесь же можно изменить h1 заголовок, добавив
в extra_content {'title': self.app_label} '''
def wrap(request, app_label, extra_context=None):
requested_app_label = resolve(request.path).kwargs.get('app_label', '')
if requested_app_label and requested_app_label == self.native_app_label:
app_label = self.string_with_realoaded_title(self.native_app_label,
self.app_label)
else:
app_label = requested_app_label
return f(request, app_label, extra_context=None)
return wrap
def main(self):
''' Оборачивает стандартные функции нашими декораторами. '''
admin.site.register = self.rename_app_label(admin.site.register)
admin.site.app_index = self.rename_app_index(admin.site.app_index)
# Пример использования, где exampleapp имя нашего приложения.
# а Хабрахабр его перевод.
AppLabelRenamer(native_app_label=u'simplelms', app_label=u'Хабрахабр').main()
Осталось только вставить сорцы в admin.py вашего приложения, подставив свои аргументы (native_app_label и app_label) в конструктор класса и запустив main().
Класс string_with_realoaded_title взят отсюда.
Спасибо за внимание.