在Django表单中,定制SelectField和SelectMultipleField [英] In Django form, custom SelectField and SelectMultipleField

查看:123
本文介绍了在Django表单中,定制SelectField和SelectMultipleField的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我每天都在使用Django三个月,真的很棒。快速的Web应用程序开发。

I am using Django everyday now for three month and it is really great. Fast web application development.

我还有一件事我不能完全按照我想做的。
这是SelectField和SelectMultiple字段。

I have still one thing that I cannot do exactly how I want to. It is the SelectField and SelectMultiple Field.

我希望能够把一些参数放在Select的选项上。

I want to be able to put some args to an option of a Select.

我终于成功与optgroup:

I finally success with the optgroup :

class EquipmentField(forms.ModelChoiceField):
    def __init__(self, queryset, **kwargs):
        super(forms.ModelChoiceField, self).__init__(**kwargs)
        self.queryset = queryset
        self.to_field_name=None

        group = None
        list = []
        self.choices = []

        for equipment in queryset:
            if not group:
                group = equipment.type

            if group != equipment.type:
                self.choices.append((group.name, list))
                group = equipment.type
                list = []
            else:
                list.append((equipment.id, equipment.name))

但是对于另一个ModelForm,我哈ve改变每个选项的背景颜色,使用模型的颜色属性。

But for another ModelForm, I have to change the background color of every option, using the color property of the model.

你知道我该怎么做吗?

谢谢。

推荐答案

你需要做的是改变由小部件。默认是选择的小部件,因此您可以将其子类化。它看起来像这样:

What you need to do, is to change the output which is controlled by the widget. Default is the select widget, so you can subclass it. It looks like this:

class Select(Widget):
    def __init__(self, attrs=None, choices=()):
        super(Select, self).__init__(attrs)
        # choices can be any iterable, but we may need to render this widget
        # multiple times. Thus, collapse it into a list so it can be consumed
        # more than once.
        self.choices = list(choices)

    def render(self, name, value, attrs=None, choices=()):
        if value is None: value = ''
        final_attrs = self.build_attrs(attrs, name=name)
        output = [u'<select%s>' % flatatt(final_attrs)]
        options = self.render_options(choices, [value])
        if options:
            output.append(options)
        output.append('</select>')
        return mark_safe(u'\n'.join(output))

    def render_options(self, choices, selected_choices):
        def render_option(option_value, option_label):
            option_value = force_unicode(option_value)
            selected_html = (option_value in selected_choices) and u' selected="selected"' or ''
            return u'<option value="%s"%s>%s</option>' % (
                escape(option_value), selected_html,
                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)

这是一个很多代码。但是您需要做的是使用改变的渲染方法来创建自己的窗口小部件。它是渲染方法,用于确定创建的html。在这种情况下,您需要更改 render_options 方法。在这里,您可以包括一些支票,以确定何时添加一个类,您可以使用这个样式。

It's a lot of code. But what you need to do, is to make your own widget with an altered render method. It's the render method that determines the html that is created. In this case, it's the render_options method you need to change. Here you could include some check to determine when to add a class, which you could style.

另一件事,在你的代码上面,它看起来不像你附加最后一组选择。此外,您可能需要向查询器添加一个 order_by(),因为您需要按类型排序。您可以在init方法中执行此操作,因此您在使用表单字段时不必执行此操作。

Another thing, in your code above it doesn't look like you append the last group choices. Also you might want to add an order_by() to the queryset, as you need it to be ordered by the type. You could do that in the init method, so you don't have to do it all over when you use the form field.

这篇关于在Django表单中,定制SelectField和SelectMultipleField的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆