Django自定义字段和小部件

0 投票
2 回答
2440 浏览
提问于 2025-04-17 08:11

我正在写一个自定义字段/小部件,用来显示多个输入框,以便输入相关数据。比如说,我的产品有4个搜索框,分别是search1、search2、search3等等。与其在表单中一个个定义每个字段,我想要一个字段,能够根据需要显示任意数量的输入框(所有相关数据),根据它的长度来决定。以下是我目前的代码:

class RelatedCategoryField(forms.MultiValueField):
    """
    Custom field to display multiple input boxes for a related object
    """

    def __init__(self, max_length, sub_max_length, label):
        # sub_max_length, is the max_length of each subfield
        self.total =  max_length/sub_max_length
        self.widget = CategoryWidget(self.total, label)
        fields = ()
        for num in range(self.total):
            fields += (forms.CharField(label="%s-%s" %(label, num),
                            max_length=sub_max_length),)
        super(RelatedCategoryField, self).__init__(fields, required=False)

    def compress(self, value_list):
        if value_list:
            return value_list
        return [[] for i in self.total]

class CategoryWidget(forms.MultiWidget):
    """
    Custom widget
    """
    def __init__(self, count, label):
        self.count = count
        self.label = label
        widgets = [forms.TextInput(attrs={}) for sub in range(self.count)]
        super(CategoryWidget, self).__init__(widgets)

    def decompress(self, value):
        if value:
            return value
        return [None for i in range(self.count)]

    def format_output(self, rendered_widgets):
        """
        Customize widget rendering
        """
        return render_to_string('fields/categoryfield.html', {'fields': rendered_widgets})

基本上,我是这样调用这个字段的:

category = RelatedCategoryField(max_length=200, sub_max_length50, label="search")

然后根据sub_max_length,这个字段会决定为这个多值字段创建多少个输入框,字段的标签会是label+field#(比如search_1、search_2等等)

上面的代码运行得很好,但我遇到的问题是,显示时这个字段只显示了定义时提供的标签,然后才是输入框。我想让每个输入框都显示对应的标签。总结一下我的问题,就是在这个多值字段中,能否为每个输入框显示标签呢?

2 个回答

1

我不知道这是不是你想要的,因为这涉及到编辑模板,而不是表单。

在你的模板中,你可以这样做:

# In form_snippet.html:

{% for field in form %}
    <div class="fieldWrapper">
    {{ field.label_tag }}: {{ field }}
    </div>
{% endfor %}

来源:https://docs.djangoproject.com/en/dev/topics/forms/#customizing-the-form-template

2

我在我的应用程序中做了类似的事情,定义了一个叫做 format_output 的东西,具体如下:

    def format_output(self, rendered_widgets):
        return mark_safe(u'<p class="placewidget">%s %s %s<br />%s %s %s %s %s %s</p>' % (
            _('Name:'), rendered_widgets[1],rendered_widgets[0],
            _('ZIP:'), rendered_widgets[2],
            _('City:'), rendered_widgets[3],
            _('State:'), rendered_widgets[4],
    ))

这样可以把每个小部件单独显示出来,并且带上它的标签。希望这对你有帮助。

撰写回答