开头很简单:
class Question(models.Model):
question_string = models.CharField(max_length=255)
answers = models.CharField(max_length=255)
答案是字符串列表的json,例如['是','否']。答案数量是动态的。 我现在面临的挑战是为这个模型写一个表格。
现状是:
class NewQuestionForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(NewQuestionForm, self).__init__(*args, **kwargs)
if self.instance:
self.fields['answers'] = AnswerField(num_widgets=len(json.loads(self.instance.answers)))
class Meta:
model = Question
fields = ['question']
widgets = {
'question': forms.TextInput(attrs={'class': "form-control"})
}
class AnswerField(forms.MultiValueField):
def __init__(self, num_widgets, *args, **kwargs):
list_fields = []
list_widgets = []
for garb in range(0, num_widgets):
field = forms.CharField()
list_fields.append(field)
list_widgets.append(field.widget)
self.widget = AnswerWidget(widgets=list_widgets)
super(AnswerField, self).__init__(fields=list_fields, *args, **kwargs)
def compress(self, data_list):
return json.dumps(data_list)
class AnswerWidget(forms.MultiWidget):
def decompress(self, value):
return json.loads(value)
问题是:我得到'JSON对象必须是str,而不是带有'{{field}}'的模板中的'NoneType''
有什么问题?
答案 0 :(得分:1)
我发现了问题。我忘了在Meta'字段'类中添加“答案”。
所以我从Model创建的动态Multiwidget示例是:
class NewQuestionForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
# need this to create right number of fields from POST
edit_mode = False
if len(args) > 0:
edit_mode = True
answer_fields = 0
for counter in range(0, 20):
answer_key = "answers_" + str(counter)
if args[0].get(answer_key, None) is not None:
answer_fields = counter + 1
else:
break
super(NewQuestionForm, self).__init__(*args, **kwargs)
if edit_mode:
self.fields['answers'] = AnswerField(num_widgets=answer_fields, required=False)
# get number of fields from DB
elif 'instance' in kwargs:
self.fields['answers'] = AnswerField(num_widgets=len(json.loads(self.instance.answers)), required=False)
else:
self.fields['answers'] = AnswerField(num_widgets=1, required=False)
class Meta:
model = Question
fields = ['question', 'answers']
widgets = {
'question': forms.TextInput(attrs={'class': "form-control"})
}
def clean_answers(self):
temp_data = []
for tdata in json.loads(self.cleaned_data['answers']):
if tdata != '':
temp_data.append(tdata)
if not temp_data:
raise forms.ValidationError('Please provide at least 1 answer.')
return json.dumps(temp_data)
'clean_answers'有2个门户:1。删除空答案。 2.我未能在第一个小部件上设置必需属性。所以我在这里检查至少有一个答案存在
class AnswerWidget(forms.MultiWidget):
def decompress(self, value):
if value:
return json.loads(value)
else:
return ['']
class AnswerField(forms.MultiValueField):
def __init__(self, num_widgets, *args, **kwargs):
list_fields = []
list_widgets = []
for loop_counter in range(0, num_widgets):
list_fields.append(forms.CharField())
list_widgets.append(forms.TextInput(attrs={'class': "form-control"}))
self.widget = AnswerWidget(widgets=list_widgets)
super(AnswerField, self).__init__(fields=list_fields, *args, **kwargs)
def compress(self, data_list):
return json.dumps(data_list)