Как изменить значение empty_label в поле ModelChoiceField в Django?

В Django я использую ModelChoiceField с параметром empty_label, чтобы позволить пользователям не выбирать значение в выпадающем списке. Вот код:

department = forms.ModelChoiceField(
    queryset=Department.objects.all(),
    label="Department",
    required=False,
    empty_label="------"  # Add an empty option
)

Это прекрасно работает, но поведение по умолчанию присваивает пустую строку («») в качестве значения для параметра empty_label. К сожалению, одна из используемых мною библиотек JavaScript не обрабатывает значения пустой строки должным образом.

Мне нужно присвоить пользовательское значение (например, -1) для параметра empty_label, но при этом сохранить его функциональность для «снятия выделения» текущего объекта.

Я пробовал переопределять варианты в методе init, например, так:

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.fields['department'].widget.choices = [("-1", "------")] + list(
        self.fields['department'].queryset.values_list('id', 'name')
    )

Однако, когда я делаю это, функциональность не работает так, как ожидалось - она не позволяет выбрать опцию «unselect», как это происходит с пустой_меткой.

Как я могу изменить значение empty_label (из пустой строки) на -1 и сохранить прежнее поведение снятия выбора?

Заранее спасибо за помощь!

Вы можете написать свой собственный с помощью патча ModelChoiceIterator:

from django.forms.models import ModelChoiceIterator


class MyModelChoiceIterator(ModelChoiceIterator):
    def __iter__(self):
        if self.field.empty_label is not None:
            yield ('-1', self.field.empty_label)
        queryset = self.queryset
        if not queryset._prefetch_related_lookups:
            queryset = queryset.iterator()
        for obj in queryset:
            yield self.choice(obj)

Затем подключите это как в подклассе ModelChoiceField: MyModelChoiceField:

from django.forms.models import ModelChoiceField


class MyModelChoiceField(ModelChoiceField):
    iterator = MyModelChoiceIterator
    empty_values = [*ModelChoiceField.empty_values, '-1']

и затем вставьте это поле модели в вашу форму.

Вернуться на верх