2010-03-05 35 views
5

Làm cách nào để tạo trường Django tự hiển thị dưới dạng cặp trường nhập ?Tạo trường biểu mẫu Django tùy chỉnh sử dụng hai số <input> s

Lý do: Tôi đang cố viết trường tùy chỉnh mới. Tôi sẽ sử dụng nó cho một dịch vụ giống như captcha . Dịch vụ hoạt động bằng cách yêu cầu câu hỏi - sau đó nhận được một và một mã thông báo . Xác thực xảy ra bằng cách gửi câu trả lời cùng với mã thông báo . Tôi muốn viết một trường biểu mẫu gói gọn logic này. Các yếu tố cần render (IMO) như

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

Và trên trình tôi cần những giá trị của _tokenanswer để xác nhận câu trả lời.

Trả lời

2

Hãy xem qua số SelectDateWidget. Nó tách đầu vào của một ngày thành ba hộp chọn.

Và chuỗi doc nói:

này cũng đóng vai trò như một ví dụ về một Widget rằng có nhiều hơn một phần tử HTML và do đó thực hiện value_from_datadict.

9

Tôi nghĩ rằng bạn đang tìm kiếm MultiWidget, bạn có thể chỉ cần cung cấp cho nó 2 tiện ích thông thường và nó sẽ hiển thị kết hợp.

4

Ở đây bạn có một ví dụ sẵn sàng (lấy từ blog của tôi):

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 

Ví dụ làm thế nào để sử dụng:

>>> 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'} 
+0

Một trong những lĩnh vực là một 'CharField' được trả lại với' HiddenInput '. Bất kỳ ý tưởng làm thế nào điều này có thể được dân cư ban đầu (trong constructor có lẽ)? –

Các vấn đề liên quan