У меня есть модель местоположения и связанная форма, которая отображает поле «местоположение» в виде набора переключателей (используя набор запросов формы для отображения значений).Есть небольшое количество локаций, но они должны быть динамичными.Я хотел бы отобразить описание местоположения рядом с каждой опцией радиоблока, чтобы у пользователей было немного больше информации о местоположениях.
Притворимся, что это список переключателей, вот как я бы хотел, чтобы он выглядел:
<> Восток - это местоположение на восток.<> Запад - это западное место!<> Север - это северное местоположение
У меня есть модель, подобная следующей:
class Location(models.Models):
location = models.CharField(max_length=50)
description = models.TextField(blank=True, null=True)
И форма как таковая:
class LocationForm(forms.Form):
location = ExtraModelChoiceField(
widget=RadioSelect(renderer=ExtraHorizRadioRenderer),
queryset = models.Locations.objects.filter(active=True))
Я могуКажется, я не нашел хорошего способа визуализации формы, чтобы я мог отобразить описание вместе с каждым параметром выбора.Я сделал много переопределений, но мне не слишком повезло.
МОЯ ПОПЫТКА РЕШЕНИЯ (НО УДАЧИ ЕЩЕ):
Исходя из того, что я понял, обычно, если в поле формы предоставляется набор запросов, логика формы Django преобразует это в выборочный наборtupals.Каждый «subtupal» содержит идентификатор и метку, которые отображаются при визуализации.Я пытаюсь добавить третье значение к тем "подзаголовкам", которое будет описанием.
Я определил пользовательский рендерер для отображения моих переключателей по горизонтали и передачи своих пользовательских настроек.
class ExtraHorizRadioRenderer(forms.RadioSelect.renderer):
def render(self):
return mark_safe(u'\n'.join([u'%s\n' % w for w in self]))
def __iter__(self):
for i, choice in enumerate(self.choices):
yield ExtraRadioInput(self.name, self.value,
self.attrs.copy(), choice, i)
def __getitem__(self, idx):
choice = self.choices[idx] # Let the IndexError propogate
return ExtraRadioInput(self.name, self.value,
self.attrs.copy(), choice, idx)
Я переопределил класс RadioJput Django, поэтому я могу добавить информацию описания, которую мне нужно отобразить рядом с кнопками Radio.
class ExtraRadioInput(forms.widgets.RadioInput):
def __init__(self, name, value, attrs, choice, index):
self.name, self.value = name, value
self.attrs = attrs
self.choice_value = force_unicode(choice[0])
self.choice_label = force_unicode(choice[1])
self.choice_description = force_unicode(choice[2]) # <--- MY ADDITION; FAILS
self.index = index
def __unicode__(self):
if 'id' in self.attrs:
label_for = ' for="%s_%s"' % (self.attrs['id'], self.index)
else:
label_for = ''
choice_label = conditional_escape(force_unicode(self.choice_label))
return mark_safe(u'<label%s>%s %s</label>' % (
label_for, self.tag(), choice_label))
def tag(self):
if 'id' in self.attrs:
self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index)
final_attrs = dict(self.attrs, type='radio', name=self.name,
value=self.choice_value)
if self.is_checked():
final_attrs['checked'] = 'checked'
return mark_safe(
u'<input%s /><span class="description">%s</span>' % \
(flatatt(final_attrs),self.choice_description )) # <--- MY ADDTIONS
Я также переопределил следующие два класса Django в надежде обойти мои модифицированные варианты выбора.
class ExtraModelChoiceIterator(forms.models.ModelChoiceIterator ):
def choice(self, obj):
if self.field.to_field_name:
key = obj.serializable_value(self.field.to_field_name)
else:
key = obj.pk
if obj.description: # <-- MY ADDITIONS
description = obj.description
else:
description = ""
return (key, self.field.label_from_instance(obj),description)
class ExtraModelChoiceField(forms.models.ModelChoiceField):
def _get_choices(self):
if hasattr(self, '_choices'):
return self._choices
return ExtraModelChoiceIterator(self) # <-- Uses MY NEW ITERATOR
Используя описанный выше подход, я не могу обойти свой трехзначный тупал.Я получаю ошибку «индекс кортежа вне диапазона» (вверх, где я отмечаю FAILURE выше), указывающий, что каким-то образом у моего тупала нет дополнительного значения.
Кто-нибудь видит недостаток в моей логике или, в более общем случае, есть подход к отображению описания рядом со списком вариантов с помощью виджета?
Спасибо за чтение.Любые комментарии очень ценятся.Джо