2
class CreateCourseForm(ModelForm):
        category = forms.ModelChoiceField(
            queryset=Category.objects.all(),
            empty_label="",
            #widget=CustomCourseWidget()
        )

    class Meta:
        model = Course
        fields = ('title', 'description', 'category')

    def __init__(self, *args, **kwargs):
        super(CreateCourseForm, self).__init__(*args, **kwargs)
        self.fields['category'].widget.attrs['class'] = 'chzn-select'
        self.fields['category'].widget.attrs['data-placeholder'] = u'Please select one'

使用上面的代码,我得到了一个选择框,其中列出了所有类别对象。我想要做的是添加一个

<optgroup>VALUE</optgroup> 

HTML 元素到特定的 Category-Objects(具有 Category.parent == null 的那些)。

有谁知道这是怎么做到的吗?非常感谢!

PS:我已经尝试将 QuerySet 转换为 Choices-Set(例如http://dealingit.wordpress.com/2009/10/26/django-tip-showing-optgroup-in-a-modelform/),效果很好用于呈现 HTML - 直到我尝试将结果保存到发生不匹配(ValueError)的数据库中。

4

1 回答 1

1

这是我目前的解决方案。这可能是一个肮脏的修复,但它工作正常:-)

class CustomCourseWidget(forms.Select):
    #http://djangosnippets.org/snippets/200/
    def render(self, name, value, attrs=None, choices=()):
        from django.utils.html import escape
        from django.utils.encoding import smart_unicode
        from django.forms.util import flatatt

        if value is None:
            value = ''
        final_attrs = self.build_attrs(attrs, name=name)
        output = [u'<select%s>' % flatatt(final_attrs)]
        output.append(u'<option value=""></option>') # Empty line for default text
        str_value = smart_unicode(value)
        optgroup_open = False
        for group in self.choices:
            option_value = smart_unicode(group[0])
            option_label = smart_unicode(group[1])
            if not ">" in option_label and optgroup_open == True:
                output.append(u'</optgroup>')
                optgroup_open = False
            if not ">" in option_label and optgroup_open == False:
                output.append(u'<optgroup label="%s">' % escape(option_label))
                optgroup_open = True
            if " > " in option_label:
                #optgroup_open = True
                selected_html = (option_value == str_value) and u' selected="selected"' or ''
                output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(option_label.split(" > ")[1])))

        output.append(u'</select>')
        return mark_safe(u'\n'.join(output))
于 2012-09-07T07:30:21.080 回答