【问题标题】:Add div wrapper to each select in SelectDateWidget将 div 包装器添加到 SelectDateWidget 中的每个选择
【发布时间】:2014-08-08 11:10:57
【问题描述】:

是否可以覆盖 SelectDateWidget 以围绕每个选择包装一个 div?

像这样:

<div class="wrapper">
<select class="selectdatewidget form-control" id="id_birthdate_day" name="birthdate_day">
<option value="0">---</option>....
</select>
</div>

<div class="wrapper">
<select class="selectdatewidget form-control" id="id_birthdate_month" name="birthdate_month">
<option value="0">---</option>....
</select>
</div>

<div class="wrapper">
<select class="selectdatewidget form-control" id="id_birthdate_year" name="birthdate_year">
<option value="0">---</option>....
</select>
</div>

【问题讨论】:

  • 你还没有关闭你的 div ;)
  • div 现已关闭;)

标签: django django-forms


【解决方案1】:

您可以继承 SelectDateWidget 并覆盖其中的渲染方法。之后,您可以在表单中使用您的 CustomSelectDateWidget。

例如:

class CustomSelectDateWidget (SelectDateWidget):
"""Override of the standard renderer used for SelectDateWidget"""    

    def render(self, name, value, attrs=None):
        try:
            year_val, month_val, day_val = value.year, value.month, value.day
        except AttributeError:
            year_val = month_val = day_val = None
            if isinstance(value, six.string_types):
                if settings.USE_L10N:
                    try:
                        input_format = get_format('DATE_INPUT_FORMATS')[0]
                        v = datetime.datetime.strptime(value, input_format)
                        year_val, month_val, day_val = v.year, v.month, v.day
                    except ValueError:
                        pass
                else:
                    match = RE_DATE.match(value)
                    if match:
                        year_val, month_val, day_val = [int(v) for v in match.groups()]
        choices = [(i, i) for i in self.years]
        year_html = self.create_select(name, self.year_field, value, year_val, choices)
        choices = list(six.iteritems(MONTHS))
        month_html = self.create_select(name, self.month_field, value, month_val, choices)
        choices = [(i, i) for i in range(1, 32)]
        day_html = self.create_select(name, self.day_field, value, day_val,  choices)

        output = []
        for field in _parse_date_fmt():
            if field == 'year':
                output.append('<div class="wrapper">' + year_html + '</div>')
            elif field == 'month':
                output.append('<div class="wrapper">' + month_html + '</div>')
            elif field == 'day':
                output.append('<div class="wrapper">' + day_html + '</div>')
        return mark_safe('\n'.join(output))`

重要的一点是在代码的末尾。这应该有效,但未经测试。我建议从您自己的 Django 中的 SelectDateWidge 版本(我正在运行 Django 1.5)中复制渲染方法并覆盖附加 div 的部分。

【讨论】:

    【解决方案2】:

    为了扩展@BogdiG 所说的内容,将包装器作为字符串传递给小部件会更有用,这样它更通用且可重用。

    class MySelectDateWidget(SelectDateWidget):
    
        def __init__(self, attrs=None, years=None, required=True, wrapper='%s'):
            self.wrapper = wrapper
    
    
        def render(self, name, value, attrs=None):
    
            # don't forget to put the rest of the render()
            # in here if you want to copy/paste this
    
            output = []
            for field in _parse_date_fmt():
                if field == 'year':
                    output.append(self.wrapper % year_html)
                elif field == 'month':
                    output.append(self.wrapper % month_html)
                elif field == 'day':
                    output.append(self.wrapper % day_html)
            return mark_safe('\n'.join(output))`
    
    
    class MyForm(forms.ModelForm):
        dob = forms.DateField(
            label=_('Date of birth'),
            widget=SelectDateWidget(wrapper='<div class="wrapper">%s</div>')
        )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-22
      • 2022-07-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-30
      • 1970-01-01
      相关资源
      最近更新 更多