【发布时间】:2023-04-09 08:23:01
【问题描述】:
我正在用 Django 编写一个预测应用程序。在基本层面上,它从 API 中提取比赛,填充数据库,最后允许用户对尚未播放的比赛进行预测。因为我不知道在比赛之前会有多少场比赛,所以我想创建一个表单,可以根据需要动态添加尽可能多的字段。
我目前有一个“工作”版本,但它会进一步产生问题。这是工作版本:(公平警告,这是我在测试,所以请原谅命名约定)
views.py
def ftest(request, contest_id):
matches_list = Matches.objects.filter(
matches_contest_pk__id = contest_id
).filter(
matches_complete = False
).order_by(
'-matches_start_time'
)
matches = [
f'{match.matches_team_1} vs. {match.matches_team_2}'
for match in matches_list
]
if request.method == 'POST':
form = TestForm(form_fields = matches, data=request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
print(form.errors)
else:
form = TestForm(form_fields = matches)
context = {
'form': form,
}
return render(request, 'predictions/test.html', context)
forms.py
from django import forms
from .models import Matches
class TestForm(forms.Form):
def __init__(self, *args, **kwargs):
form_fields = kwargs.pop('form_fields', None)
super(TestForm, self).__init__(*args, **kwargs)
for field in form_fields:
self.fields[field] = forms.CharField(label = f'{field}', max_length = 100)
正如我所说,这可行,但理想情况下,我希望将每个字段的 id 设置为数据库中的实际 id。我对此的解决方案是更改视图以通过form_fields 发送字典列表,并更新表单以使用它。这就是它的样子:
views.py
def ftest(request, contest_id):
matches_list = Matches.objects.filter(
matches_contest_pk__id = contest_id
).filter(
matches_complete = False
).order_by(
'-matches_start_time'
)
matches = [
{ 'label': f'{match.matches_team_1} vs. {match.matches_team_2}', 'id': match.id, }
for match in matches_list
]
if request.method == 'POST':
form = TestForm(form_fields = matches, data=request.POST)
if form.is_valid():
return HttpResponseRedirect('/thanks/')
else:
print(form.errors)
else:
form = TestForm(form_fields = matches)
context = {
'form': form,
}
return render(request, 'predictions/test.html', context)
forms.py
from django import forms
from .models import Matches
class TestForm(forms.Form):
def __init__(self, *args, **kwargs):
form_fields = kwargs.pop('form_fields', None)
super(TestForm, self).__init__(*args, **kwargs)
for field in form_fields:
self.fields[field['id']] = forms.CharField(label = field['label'], max_length = 100)
但是,通过此更改,表单无法通过验证。它只是为每个字段抛出一个This field is required. 错误。理想情况下,我希望用户返回到同一页面并在字段中填写他们的预测。关于如何解决这个问题的任何建议?我是从错误的角度解决问题还是我误解了表单在 Django 中的工作方式?
【问题讨论】:
标签: django django-forms