Django: глобальная модификация внешнего вида поля только для чтения - PullRequest
0 голосов
/ 05 марта 2019

Я хочу настроить текстуру поля в новом « режиме только для чтения» django : например, внешние ключи должны отображаться в виде ссылок.

В общем, я определил следующие параметры:

  • Реализация настраиваемых полей для каждой модели - приводит к дублированию кода
  • Переопределение метода display_for_field в django

По сути, я могу скопировать и вставить django.contrib.admin.utilsмодуль, вставьте мои изменения, переопределите sys.modules['django.contrib.admin.utils'] = myutils, но это уродливо из-за ремонтопригодности в случае обновления Django в будущем.

Поэтому я решил переопределить только метод display_for_fields django.contrib.admin.utils, используя следующий подход, чтобы избежатьдублирование кода Django:

  1. Переопределить функцию display_for_field в django.contrib.admin.utils в settings.py:

    from myapp.contrib.admin import utils
    utils.override_method()
    
  2. В myapp.utils.py:

    from django.contrib.admin import utils
    from django.contrib.admin.utils import *
    
    
    def display_for_field_mod(value, field, empty_value_display):
        if isinstance(field, models.ForeignKey) and value:
            if field.related_model.__name__.lower() != 'user':
                link_string = 'admin:myapp_' + field.related_model.__name__.lower() + '_change'
                link = reverse(link_string, args=(value.id,))
                return format_html('<a href="{}">{}</a>', link, value)
            else:
                return formats.localize(value)
        else:
            return display_for_field(value, field, empty_value_display)
    
    
    def override_method():
        utils.display_for_field = display_for_field_mod
    

Но проблема в том, что display_for_field импортируется в django.contrib.admin.helpers с использованием:

    from django.contrib.admin.utils import (
        display_for_field, [...]
    )

Так что из-за объема импортируемой функции я не могу переопределить эту функцию извне.

Я пропускаю какую-то другую очевидную возможность?Есть ли чистый метод для достижения этой цели, или это единственный вариант для дублирования / изменения исходного кода django?

...