如何在HTML中为ModelChoiceField的选项设置标题和类?

时间:2010-06-07 21:24:50

标签: django django-forms

我有一个模特

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的默认输出之间的差异是OPTION标记中的标题和类元素。 ModelChoiceField的默认输出中不存在它们。

出于我的目的:

  • 标题元素应该是选项名称。
  • 类元素应该是self.parent.name。 (这是我的问题

因此,在上面的HTML代码段中,值1没有父级,值2的父级值为1。

更改ModelChoiceField默认HTML输出的最佳机制是什么?


编辑:我了解如何创建用于呈现HTML的新Widget。问题是如何在每个选项中从底层模型中呈现值。

2 个答案:

答案 0 :(得分:2)

您可以创建自己的小部件:

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 :(得分:1)

查看我的示例,了解如何在this post

中创建自定义字段