Настроить/удалить опцию выбора Django
Я использую Django 1.0.2. Я написал ModelForm, поддерживаемый моделью. Эта модель имеет ForeignKey, где blank = False. Когда Django генерирует HTML для этой формы, он создает поле выбора с одним параметром для каждой строки в таблице, на которую ссылается ForeignKey. Он также создает опцию в верхней части списка, которая не имеет значения и отображается как серия тире:
<option value="">---------</option>
Что я хотел бы знать:
- Каков самый чистый способ удалить этот автоматически сгенерированный параметр из окна выбора?
-
Каков самый чистый способ настроить его так, чтобы он отображался как:
<option value="">Select Item</option>
В поисках решения я столкнулся с Django ticket 4653, который дал мне впечатление, что у других был тот же вопрос и что поведение по умолчанию Возможно, Django был изменен. Этот билет старше года, поэтому я надеялся, что может быть более чистый способ выполнить эти вещи.
Спасибо за любую помощь,
Джефф
Изменить: я настроил поле ForeignKey как таковое:
verb = models.ForeignKey(Verb, blank=False, default=get_default_verb)
Это устанавливает значение по умолчанию, так что оно больше не является параметром empty/dashes, но, к сожалению, это не похоже на решение моих вопросов. То есть параметр empty/dashes все еще отображается в списке.
Ответы
Ответ 1
Не тестировал это, но на основе чтения кода Django здесь и здесь Я считаю, что он должен работать:
class ThingForm(models.ModelForm):
class Meta:
model = Thing
def __init__(self, *args, **kwargs):
super(ThingForm, self).__init__(*args, **kwargs)
self.fields['verb'].empty_label = None
РЕДАКТИРОВАТЬ: документально, хотя вы не обязательно должны знать ModelChoiceField, если вы работая с автогенерированным ModelForm.
РЕДАКТИРОВАТЬ. Как отмечает jlpp в своем ответе, это не является полным - вам нужно повторно назначить выбор виджетам после изменения атрибута empty_label. Поскольку это немного взломано, другой вариант, который может быть проще понять, просто переопределяет весь ModelChoiceField:
class ThingForm(models.ModelForm):
verb = ModelChoiceField(Verb.objects.all(), empty_label=None)
class Meta:
model = Thing
Ответ 2
из документов
Пустой выбор не будет включен если поле модели имеет пустое value = False и явное значение по умолчанию (значение по умолчанию значение будет первоначально выбрано вместо этого).
поэтому установите значение по умолчанию, и вы в порядке
Ответ 3
С ответом Карла в качестве руководства и после укоренения вокруг источника Django в течение нескольких часов я думаю, что это полное решение:
-
Чтобы удалить пустую опцию (пример Карла):
class ThingForm(models.ModelForm):
class Meta:
model = Thing
def __init__(self, *args, **kwargs):
super(ThingForm, self).__init__(*args, **kwargs)
self.fields['verb'].empty_label = None
# following line needed to refresh widget copy of choice list
self.fields['verb'].widget.choices =
self.fields['verb'].choices
-
Чтобы настроить пустую метку, по сути, она та же:
class ThingForm(models.ModelForm):
class Meta:
model = Thing
def __init__(self, *args, **kwargs):
super(ThingForm, self).__init__(*args, **kwargs)
self.fields['verb'].empty_label = "Select a Verb"
# following line needed to refresh widget copy of choice list
self.fields['verb'].widget.choices =
self.fields['verb'].choices
Я думаю, что этот подход применим ко всем сценариям, где ModelChoiceFields отображаются как HTML, но я не уверен. Я обнаружил, что при инициализации этих полей их выбор передается в виджет "Выбор" (см. Django.forms.fields.ChoiceField._set_choices). Установка пустого_класса после инициализации не обновляет список выбора виджетов. Я недостаточно знаком с Django, чтобы узнать, следует ли это считать ошибкой.
Ответ 4
Вы можете использовать это в своей модели:
class MyModel(models.Model):
name = CharField('fieldname', max_length=10, default=None)
default = None - ответ: D
ПРИМЕЧАНИЕ. Я пробовал это на Django 1.7
Ответ 5
Что касается django 1.4, все, что вам нужно, это установить "значение по умолчанию" и "blank = False" в поле выбора
class MyModel(models.Model):
CHOICES = (
(0, 'A'),
(1, 'B'),
)
choice_field = models.IntegerField(choices=CHOICES, blank=False, default=0)
Ответ 6
См. здесь для полного обсуждения и методов решения этой проблемы.
Ответ 7
вы можете сделать это в admin:
formfield_overrides = {
models.ForeignKey: {'empty_label': None},
}
Ответ 8
self.fields['xxx'].empty_value = None
не работает Если вы задаете тип поля TypedChoiceField
, у которого нет свойства empty_label
.
Нам нужно сделать первый выбор:
1. Если вы хотите создать автоматическое обнаружение BaseForm
TypedChoiceField
class BaseForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(BaseForm, self).__init__(*args, **kwargs)
for field_name in self.fields:
field = self.fields.get(field_name)
if field and isinstance(field , forms.TypedChoiceField):
field.choices = field.choices[1:]
# code to process other Field
# ....
class AddClientForm(BaseForm):
pass
2. только несколько форм, вы можете использовать:
class AddClientForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(AddClientForm, self).__init__(*args, **kwargs)
self.fields['xxx'].choices = self.fields['xxx'].choices[1:]
Ответ 9
Я сегодня возился с этим и только что придумал решение pust hack:
# Cowardly handle ModelChoiceField empty label
# we all hate that '-----' thing
class ModelChoiceField_init_hack(object):
@property
def empty_label(self):
return self._empty_label
@empty_label.setter
def empty_label(self, value):
self._empty_label = value
if value and value.startswith('-'):
self._empty_label = 'Select an option'
ModelChoiceField.__bases__ += (ModelChoiceField_init_hack,)
Теперь вы можете настроить по умолчанию ModelChoiceField
пустую метку на все, что хотите.: -)
PS: Нет необходимости в downvotes, не пагубные патчи обезьяны всегда удобны.
Ответ 10
Для последней версии django
первый ответ должен быть таким:
class ThingForm(models.ModelForm):
class Meta:
model = Thing
def __init__(self, *args, **kwargs):
self.base_fields['cargo'].empty_label = None
super(ThingForm, self).__init__(*args, **kwargs)`
Ответ 11
Я нахожу РЕШЕНИЕ!!
Но не для ForeignKey: -)
Может быть, я могу вам помочь.
Я посмотрел в исходном коде Django и обнаружил, что в django.forms.extras.widgets.SelecteDateWidget() - это свойство, называемое none_value, которое равно (0, '-----'), поэтому я сделал в своем коде этот
class StudentForm(ModelForm):
class Meta:
this_year = int(datetime.datetime.today().strftime('%Y'))
birth_years = []
years = []
for year in range(this_year - 2, this_year + 3 ):
years.append(year)
for year in range(this_year - 60, this_year+2):
birth_years.append(year)
model = Student
exclude = ['user', 'fullname']
date_widget = SelectDateWidget(years=years)
date_widget.__setattr__('none_value', (0, 'THERE WAS THAT "-----" NO THERES THIS:-)'))
widgets = {
'beginning': date_widget,
'birth': SelectDateWidget(years=birth_years),
}
Ответ 12
В поле ForeignKey
установка значения default
на ''
на модели приведет к удалению пустого параметра.
verb = models.ForeignKey(Verb, on_delete=models.CASCADE, default='')
Для других полей, таких как CharField
, вы можете установить default
в None
, но это не работает для полей ForeignKey
в Django 1.11.