Как запретить Django Admin переопределять пользовательский виджет для настраиваемого поля? - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть поле модели, поле формы и виджет, который я использую в приложении.Детали кода не имеют значения.Ключевым моментом является то, что поле корректно отображается в обычных формах, но переопределяется в admin.

Вот некоторый псевдокод того, как поле выглядит в основном:

class SandwichWidget(forms.Widget):
    template_name = 'sandwichfield/widgets/sandwichfield.html'

    def __init__(self, attrs=None, date_format=None, time_format=None):
        widgets = (
            NumberInput(),
            Select(choices=FILLING_CHOICES),
            NumberInput(),
        )
        super(SandwichWidget, self).__init__(widgets, attrs)

    def decompress(self, value):
        if value:
            value = Sandwich(value)
            return [
                value.top,
                value.middle,
                value.bottom
            ]
        return [None, None, None]


class SandwichFormField(forms.MultiValueField):
    widget = SandwichWidget

    def __init__(self, input_date_formats=None, input_time_formats=None, *args, **kwargs):
        fields = (
            forms.IntegerField(),
            forms.CharField(),
            forms.IntegerField(),
        )
        super(SandwichFormField, self).__init__(fields, *args, **kwargs)


class SandwichField(models.PositiveIntegerField):

    def get_internal_type(self):
        return 'IntegerField'

    def formfield(self, *args, **kwargs):
        defaults={'form_class': SandwichFormField}
        defaults.update(kwargs)
        return super(SandwichField, self).formfield(*args, **defaults)

Это, очевидно, происходит потому, что эта строка в django/contrib/admin/options.py, которая определяет переопределение models.IntegerField, должна быть widgets.AdminIntegerFieldWidget.Поскольку models.PositiveIntegerField наследуется от models.IntegerField, а строка 181 зацикливается на всех подклассах поля, кажется, что нет способа предотвратить переопределение виджета в admin.

Это реальная проблема, потому что я использую это настраиваемое поле с его настраиваемым виджетом по всему сайту и через администратора, и я не хочу вводить настраиваемое значение для override_fields каждый раз, когда хочу использоватьполе.В идеале разработчики должны иметь возможность использовать настраиваемое поле без необходимости каждый раз настраивать администратора.

В настоящее время я наследую от forms.PositiveIntegerField, поскольку при сохранении и извлечении из базы данных это положительное целое числои я хочу использовать все имеющееся кодирование для обработки положительных целочисленных значений.

В настоящее время похоже, что решение only меняет мое поле для наследования от models.Fieldа затем скопировать и вставить все функциональные возможности PositiveIntegerField и IntegerField из кода django.Есть ли альтернатива этому?

Конечно, я всегда могу заставить свое поле формы игнорировать любой отправляемый виджет и всегда использовать собственный виджет, но это вызывает проблему, когда я активно хочу переопределить виджет, что абсолютно может произойти.Я просто не хочу, чтобы админ переопределил мой виджет.

1 Ответ

0 голосов
/ 06 декабря 2018

В вашей модели администратора, вы должны добавить эти виджеты в formfield_overrides.Например, вот так:

class BaseModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.CharField: {'widget': forms.Textarea},
    }

Теперь вы можете создавать подклассы всех администраторов вашей модели из этого класса, и вам не нужно писать избыточный код для переопределений.

...