Как установить заголовок и класс в HTML для параметров ModelChoiceField? - PullRequest
1 голос
/ 08 июня 2010

У меня есть модель

class MyModel(models.Model):
    name = models.CharField(max_length=80, unique=True)
    parent = models.ForeignKey('self', null=True, blank=True)

Я хочу отобразить ModelChoiceField для этой модели, которая выглядит следующим образом:

<select name="mymodel" id="id_mymodel">
    <option value="1" title="Value 1" class="">Value 1</option>
    <option value="2" title="Value 2" class="Value 1">Value 2</option>
</select>

Различия между этим выводом и выводом по умолчанию для ModelChoiceField заключаются в элементах title и class в теге OPTION. Они не существуют в выводе ModelChoiceField по умолчанию.

Для моих целей:

  • Предполагается, что элементом title является Имя опции.
  • Элемент класса должен быть self.parent.name. ( это моя проблема )

Итак, в приведенном выше фрагменте HTML у Value 1 нет родителя, а у Value 2 родительский для значения 1.

Каков наилучший механизм изменения вывода HTML по умолчанию ModelChoiceField?


РЕДАКТИРОВАТЬ: Я понимаю, как создать новый виджет для рендеринга HTML. Проблема заключается в том, как отобразить значение из базовой модели в каждом из параметров.

Ответы [ 2 ]

2 голосов
/ 08 июня 2010

Вы можете сделать свой собственный виджет:

from django.forms.widgets import Select 

class MySelect(Select):

    def __init__(self, attrs=None, choices=(), model):
       self.model = model
       super(Select, self).__init__(attrs)

    def render_options(self, choices, selected_choices):
        def render_option(option_value, option_label):
            option_value = force_unicode(option_value)
            option = self.model.objects.get(pk=option_value)
            selected_html = (option_value in selected_choices) and u' selected="selected"' or ''
            return u'<option value="%s"%s class="%s">%s</option>' % (
                escape(option_value), selected_html,
                str(obj.parent.name),
                conditional_escape(force_unicode(option_label)))
        # Normalize to strings.
        selected_choices = set([force_unicode(v) for v in selected_choices])
        output = []
        for option_value, option_label in chain(self.choices, choices):
            if isinstance(option_label, (list, tuple)):
                output.append(u'<optgroup label="%s">' % escape(force_unicode(option_value)))
                for option in option_label:
                    output.append(render_option(*option))
                output.append(u'</optgroup>')
            else:
                output.append(render_option(option_value, option_label))
        return u'\n'.join(output)

Если вы также хотите использовать метку поля: у класса поля есть метод label_from_instance.

1 голос
/ 08 июня 2010

Посмотрите на мой пример о том, как создавать настраиваемые поля в этом посте

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...