【问题标题】:Creating a custom Django form field that uses two <input>s创建一个使用两个 <input> 的自定义 Django 表单字段
【发布时间】:2010-03-05 12:11:24
【问题描述】:

如何创建一个将自身呈现为一对输入的 Django 字段 字段?

推理:我正在尝试编写一个新的自定义字段。我会用它 类似验证码的服务。该服务通过提出问题来工作 - 然后收到一个和一个 token。验证通过发送 answer 以及 token。我想写一个表单域 封装了这个逻辑。元素应该像(IMO)一样呈现

<input type="hidden" name="_token" value="1234567890" />
<input type="text" name="answer" />

在提交时,我需要 _tokenanswer 的值来验证答案。

【问题讨论】:

    标签: python django django-forms


    【解决方案1】:

    我认为您正在寻找 MultiWidget,您只需给它 2 个常规小部件,它就会呈现组合。

    【讨论】:

      【解决方案2】:

      这里有一个现成的例子(摘自我的博客):

      class ComplexMultiWidget(forms.MultiWidget):
          def __init__(self, attrs=None):
              widgets = (
                  forms.TextInput(),
                  forms.SelectMultiple(choices=(('J', 'John'),
                                                ('P', 'Paul'),
                                                ('G', 'George'),
                                                ('R', 'Ringo'))),
                  forms.SplitDateTimeWidget(),
              )
              super(ComplexMultiWidget, self).__init__(widgets, attrs)
      
          def decompress(self, value):
              if value:
                  data = value.split(',')
                  return [data[0], data[1],
                         datetime.datetime(*time.strptime(data[2],
                         "%Y-%m-%d %H:%M:%S")[0:6])]
              return [None, None, None]
          def format_output(self, rendered_widgets):
              return u'\n'.join(rendered_widgets)
      
      
      class ComplexField(forms.MultiValueField):
          def __init__(self, required=True, widget=None, label=None, initial=None):
              fields = (
                  forms.CharField(),
                  forms.MultipleChoiceField(choices=(('J', 'John'),
                                                     ('P', 'Paul'),
                                                     ('G', 'George'),
                                                     ('R', 'Ringo'))),
                  forms.SplitDateTimeField()
              )
              super(ComplexField, self).__init__(fields, required,
                                                 widget, label, initial)
      
          def compress(self, data_list):
              if data_list:
                  return '%s,%s,%s' % (data_list[0],''.join(data_list[1]),
                                       data_list[2])
              return None
      

      使用示例:

      >>> f = ComplexField(widget=ComplexMultiWidget())
      >>> f.clean(['some text', ['J','P'], ['2007-04-25','6:24:00']])
      u'some text,JP,2007-04-25 06:24:00'
      >>> f.clean(['some text',['X'], ['2007-04-25','6:24:00']])
      Traceback (most recent call last):
      ...
      ValidationError: [u'Select a valid choice. X is not one of the available choices.']
      
      >>> f.clean(['some text',['JP']])
      Traceback (most recent call last):
      
      >>> class ComplexFieldForm(Form):
                  field1 = ComplexField(widget=ComplexMultiWidget())
      
      >>> f = ComplexFieldForm({'field1_0':'some text','field1_1':['J','P'], 'field1_2_0':'2007-04-25', 'field1_2_1':'06:24:00'})
      >>> print f
      <tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" value="some text" id="id_field1_0" />
      <select multiple="multiple" name="field1_1" id="id_field1_1">
      <option value="J" selected="selected">John</option>
      <option value="P" selected="selected">Paul</option>
      <option value="G">George</option>
      <option value="R">Ringo</option>
      </select>
      <input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr>
      
      >>> f.cleaned_data
      {'field1': u'some text,JP,2007-04-25 06:24:00'}
      

      【讨论】:

      • 其中一个字段是使用HiddenInput 呈现的CharField。任何想法最初如何填充(可能在构造函数中)?
      【解决方案3】:

      看看SelectDateWidget。它将日期的输入分成三个选择框。

      文档字符串说:

      这也是一个 Widget 的示例,它具有多个 HTML 元素,因此实现了value_from_datadict

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-10
        • 2014-04-30
        • 1970-01-01
        • 2015-12-12
        • 1970-01-01
        • 2015-12-09
        • 2019-01-25
        • 2019-01-22
        相关资源
        最近更新 更多