我已经开始创建表单。基本上,表单是二十个单词的“测试”。表单由二十个文本字段组成,我想包含一个单词的定义。用户将输入单词。完成后,表格应验证数据并标记正确和错误。我已经在django中完成了许多模型形式,但这是不同的。这种形式的所有数据都必须作为上下文传递。
views.py
def get_test(request, username='default'):
template_name = 'main/test.html'
if request.method == 'POST':
pass
else:
lang = Language(config('USER'), config('PASS'))
streakinfo = lang.get_streak_info()
uniquewords = lang.get_unique_words()
testwords = get_test_words(uniquewords)
wordsdict = get_word_dict(testwords)
form = TestForm()
context = {
'testwords': testwords, # list of random unique test words
'wordsdict': wordsdict, # dict of words + definitions {word: {pronounciation, definition}}
'form': form,
}
return render(request, template_name, context)
forms.py
class TestForm(forms.Form):
word_1 = forms.CharField(label='1', max_length=100)
word_2 = forms.CharField(label='2', max_length=100)
word_3 = forms.CharField(label='3', max_length=100)
word_4 = forms.CharField(label='4', max_length=100)
word_5 = forms.CharField(label='5', max_length=100)
word_6 = forms.CharField(label='6', max_length=100)
word_7 = forms.CharField(label='7', max_length=100)
word_8 = forms.CharField(label='8', max_length=100)
word_9 = forms.CharField(label='9', max_length=100)
word_10 = forms.CharField(label='10', max_length=100)
word_11 = forms.CharField(label='11', max_length=100)
word_12 = forms.CharField(label='12', max_length=100)
word_13 = forms.CharField(label='13', max_length=100)
word_14 = forms.CharField(label='14', max_length=100)
word_15 = forms.CharField(label='15', max_length=100)
word_16 = forms.CharField(label='16', max_length=100)
word_17 = forms.CharField(label='17', max_length=100)
word_18 = forms.CharField(label='18', max_length=100)
word_19 = forms.CharField(label='19', max_length=100)
word_20 = forms.CharField(label='20', max_length=100)
我的意思是,手动进行每个字段的渲染非常简单,但是我不知道并且从未做过的事情就是没有模型。例如,我要建立一个表,col 1具有定义(我实际上不需要label=##
,因为我再次将数据作为上下文传递),col 2具有该字段。如何将发布数据绑定在一起,以便在发布结果时,最有把握地将第2列与第1列进行比较?简而言之,如何手动呈现和验证表单并保持所有数据对齐?如果要提一个问题,我会提前道歉。
更新:
我能够将测试数据放入表单并使用以下(by hacking away at the forms.Form inheritance)呈现字段:
class TestForm(forms.Form):
"""
Student test form
"""
def __init__(self, testdict, *args, **kwargs):
super().__init__(*args, **kwargs)
self.testdict = {} if testdict is None else testdict
d = self.testdict
for word in d:
answer = word
for key in d[word]:
value = str(d[word][key])
if key == 'id':
field_name = value
if key == 'definition':
question = value
self.fields[field_name] = forms.CharField(label=question, max_length=100)
虽然仍然需要帮助。
答案 0 :(得分:0)
是的,您可以覆盖干净的方法,并像这样对它们实施验证:
您已经用表单类将所有字段都写好了,然后使用get实际获得了它们的name
HTML参数在这些字段中输入的内容,然后通过它们的变量处理了数据,如果没有完全符合您的期望,然后提出Validationerror
。然后,您将所有数据从这些字段创建到dict中,并为其设置变量,最后返回该变量。
forms.py
class TestForm(forms.Form):
word_1 = forms.CharField(label='1', max_length=100)
word_2 = forms.CharField(label='2', max_length=100)
word_3 = forms.CharField(label='3', max_length=100)
word_4 = forms.CharField(label='4', max_length=100)
word_5 = forms.CharField(label='5', max_length=100)
word_6 = forms.CharField(label='6', max_length=100)
word_7 = forms.CharField(label='7', max_length=100)
word_8 = forms.CharField(label='8', max_length=100)
word_9 = forms.CharField(label='9', max_length=100)
word_10 = forms.CharField(label='10', max_length=100)
word_11 = forms.CharField(label='11', max_length=100)
word_12 = forms.CharField(label='12', max_length=100)
word_13 = forms.CharField(label='13', max_length=100)
word_14 = forms.CharField(label='14', max_length=100)
word_15 = forms.CharField(label='15', max_length=100)
word_16 = forms.CharField(label='16', max_length=100)
word_17 = forms.CharField(label='17', max_length=100)
word_18 = forms.CharField(label='18', max_length=100)
word_19 = forms.CharField(label='19', max_length=100)
word_20 = forms.CharField(label='20', max_length=100)
def clean(self):
word_1 = self.cleaned_data.get("word_1")
# |
# | write the clean method of all fields
# |
# -----
# ---
# -
word_20 = self.cleaned_data.get("word_20")
if word_1 and word_2 and word_7 and word_15 != something:
raise forms.ValidationError("Something Fishy")
# i combined few of the word fields but you check all the fields separately also and implement your validation.
words_context = {
'word_1':word_1
# | <--write all the context of corresponding fields
# |
'word_20':word_20
}
return words_context
Views.py
def get_test(request, username='default'):
template_name = 'main/test.html'
form = TestForm()
if request.method == 'POST':
if form.is_valid():
word_1 = self.cleaned_data.get("word_1")
# |
# | write the clean method of all fields
# |
# -----
# ---
# -
word_20 = self.cleaned_data.get("word_20")
newtest = Test(word_1=word_1,....word_20=word_20)
newtest.save()
return redirect('whereever you want to redirect')
else:
lang = Language(config('USER'), config('PASS'))
streakinfo = lang.get_streak_info()
uniquewords = lang.get_unique_words()
testwords = get_test_words(uniquewords)
wordsdict = get_word_dict(testwords)
form = TestForm()
context = {
'testwords': testwords, # list of random unique test words
'wordsdict': wordsdict, # dict of words + definitions {word: {pronounciation, definition}}
'form': form,
}
return render(request, template_name, context)
答案 1 :(得分:0)
我完成了这两种方式:一种是写文件,另一种是写模型。由于编写模型显然更快,因此我将展示:
我认为这很简单。这里的开始是当我在GET
请求form = TestForm(wordsdict)
上实例化表单时,我将单词字典传递给该表单。 POST请求数据从未真正存储过,仅用于验证。因此,当我进行POST时,我只是正常发送POST数据。 wordsdict
是由{answer:[question,id]}
views.py
def language_test(request, username='johndoe', password=None):
lang= Language(config('USER'), config('PASS'))
streakinfo = lang.get_streak_info()
context = {
'username': username,
'streakinfo': streakinfo,
}
template_name = 'tests/test.html'
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the saved answer dictionary:
print('POSTING TEST RESULTS')
form = TestForm(data=request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
print('PASSED')
# redirect to a new URL:
return redirect('main:success')
else:
print('FAILED')
if form.has_error:
print('FORM ERROR')
pass
# if a GET (or any other method) we'll create a blank form
else:
print('GETTING NEW TEST')
phrases = lang.get_known_phrases()
testwords = get_test_words(phrases)
wordsdict = get_word_dict(testwords)
form = TestForm(wordsdict)
context['form'] = form
return render(request, template_name, context)
再往前走...
models.py
class TestAnswers(models.Model):
phraseid = models.IntegerField(unique=True, blank=True, null=True)
question = models.TextField(blank=True, null=True)
answer = models.CharField(max_length=50, blank=True, null=True)
这就是魔术发生的地方。我正在继承继承的__init__
类的Form
函数。实例化该类时,它将计算test_dict
参数,该参数可能已被视图传递,也可能未被视图传递。如果没有test_dict
,则必须是对新测试的请求,因此我清除了测试模型,并使用视图传递的随机选择的问题/答案创建了一个新模型。如果没有传递test_dict
,则它必须是发布请求,这意味着我需要验证所有答案。请参考clean方法进行表单验证。
forms.py
class TestForm(forms.Form):
"""
Student test form
"""
def __init__(self, test_dict=None, *args, **kwargs):
super().__init__(*args, **kwargs)
self._resource_path = os.path.join(settings.BASE_DIR, 'static/json')
self._json_path = os.path.join(self._resource_path, 'answers.json')
self._model = TestAnswers
i = 0
phraseid, answer, question = [], [], []
if test_dict is not None:
# A form get request should resolve new form data and
# store it in the database for comparison later on
# clear out the answers table
self._model.objects.all().delete()
# create a list of model objects to bulk insert
records = []
for item in test_dict:
record = self._model(
phraseid=test_dict[item]['id'],
answer=item,
question=test_dict[item]['definition']
)
phraseid.append(test_dict[item]['id'])
question.append(test_dict[item]['definition'])
answer.append(item)
records.append(record)
if records:
# Insert the records into the TestAnswers table
self._model.objects.bulk_create(records)
self.test_dict = test_dict
else:
# A form post request should check the form data against
# what was established during the get request
# Get all the objects in the test table
records = self._model.objects.all()
# Put all the object items into their respective lists
for r in records:
phraseid.append(r.phraseid)
answer.append(r.answer)
question.append(r.question)
for i in range(len(question)):
# Set the form fields
field_name = 'testword' + str(phraseid[i])
# Print the answers for debugging
print('id: ' + str(phraseid[i]))
print('question: ' + question[i])
print('answer:' + answer[i])
self.fields[field_name] = forms.CharField(label=question[i], max_length=100)
self.question = question
self.phraseid = phraseid
self.answer = answer
def clean(self):
# print('CLEANING DATA')
phraseid, answer, question = [], [], []
context = {}
i = 0
records = self._model.objects.all()
for r in records:
phraseid.append(r.phraseid)
answer.append(r.answer)
question.append(r.question)
# Get and check the results
for i in range(len(self.cleaned_data)):
field_name = 'testword' + str(phraseid[i])
result = self.cleaned_data.get(field_name)
if result != answer[i]:
self.add_error(field_name, 'Incorrect')
context[i] = question[i]
i += 1
return context