我正在研究一个项目的具体视图,我似乎无法弄清楚如何实现它。
我想在Django视图中动态复制单个表单,并且对于每个表单,根据查询集中的数据字段为每个表单添加前缀。然后我想将重复的表单传递到HTML中,用户可以在字段中输入信息然后提交。
问题在于我无法弄清楚如何根据查询集的结果创建具有不同前缀的重复表单。并将每个前缀分配给正在调用的用户记录的用户名。
因此,假设我有一个查询集,该查询集调用查询集来提取名称以t开头的所有用户。对于用户查询中的每个用户,我想创建一个基于inividualsplitform的表单,并为每个表单添加前缀和附加到特定用户的用户名。我想将每个表单传递给HTML模板并在HTML文件中显示表单。一旦用户填写表单,我希望能够通过相同的查询并在用户的查询中形成每个用户,使用用户名作为eay来识别每个不同的表单并提取信息。
现在发生的事情是,它为用户查询中的最后一个用户创建了一个表单,并推送该表单,只推送该表单而不是所有表单。并且只有最后一个回来由视图处理。
以下是我现在的观点:
def addTransaction(request, groupId, recordId):
user = User.objects.get(username='omar')
group = Group.objects.get(id=groupId)
record = Record.objects.get(id=recordId)
transactions = Transaction.objects.filter(record=recordId).all()
if request.method == 'POST':
if record.split == 1:
form = EvenSplitTransactionForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
amount = cd['amount']
description = cd['description']
split_amount = SplitEven(record, amount)
for trans in transactions:
if trans.record.id == record.id:
trans.description = description
trans.amount = split_amount
trans.save()
return redirect('group_home', groupId=group.id)
if record.split == 2:
# this is where i want to iterate though the formset and get the info
# that i need from the forms that the user submitted.
forms = TransFormSet()
for form in forms:
display = 'message'
print(display)
return redirect('accounts')
else:
if record.split == 1:
form = EvenSplitTransactionForm()
message = 'fill out the form below'
parameters = {
'record':record,
'form':form,
'message':message,
'transactions':transactions,
}
return render(request, 'tabs/add_even_transactions.html', parameters)
if record.split == 2:
for transaction in transactions:
form = IndividualSplitTransactionForm(prefix = transaction.user.username)
print(form)
message = 'message'
parameters = {
'record':record,
'form':form,
'message':message,
'transactions':transactions,
}
return render(request, 'tabs/add_individual_transaction.html', parameters)
更新: 我得到了表单,但我遇到了表单列表验证和与表单一起提交的信息收集问题。
def addTransaction(request, groupId, recordId):
user = User.objects.get(username='omar')
group = Group.objects.get(id=groupId)
record = Record.objects.get(id=recordId)
transactions = Transaction.objects.filter(record=recordId).all().count()
formset = formset_factory(IndividualSplitTransactionForm, extra=transactions)
if request.method == 'POST':
if record.split == 1:
form = EvenSplitTransactionForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
amount = cd['amount']
description = cd['description']
split_amount = SplitEven(record, amount)
for trans in transactions:
if trans.record.id == record.id:
trans.description = description
trans.amount = split_amount
trans.save()
return redirect('group_home', groupId=group.id)
if record.split == 2:
cheese = 'cheese'
# this is where i want to iterate though the formset and get the info
# that i need from the forms that the user submitted.
# form = formList(request.POST)
# if form.is_valid():
# cd = form.cleaned_data
# for transaction in transactions:
# amount = transaction.user.username + '-amount'
# description = transaction.user.username + '-description'
# currentAmount = cd[amount]
# currentDescription = cd[description]
# transaction.amount = currentAmount
# transaction.description = currentDescription
# transaction.save()
# return redirect('group_home', groupId=group.id)
return redirect('accounts')
else:
if record.split == 1:
form = EvenSplitTransactionForm()
message = 'fill out the form below'
parameters = {
'record':record,
'form':form,
'message':message,
'transactions':transactions,
}
return render(request, 'tabs/add_even_transactions.html', parameters)
if record.split == 2:
print(formset)
message = 'message'
parameters = {
'record':record,
'formset':formset,
'message':message,
'transactions':transactions,
}
return render(request, 'tabs/add_individual_transaction.html', parameters)
答案 0 :(得分:0)
更改标签
from django.forms import BaseFormSet
class BaseTestFormset(BaseFormSet):
def add_fields(self, form, index):
super().add_fields(form, index)
form.fields['your field name'].label = "new label"
return form
TestFormset = formset_factory(TestForm, formset=BaseTestFormSet)
如果您有用户名列表,则可以更改"新标签" as usernameList [index]
exList = ["hello", "there"]
...
def add_fields(self, form, index):
super().add_fields(form, index)
form.fields['your field name'].label = exList[index]
return form
使用Formset
if request.method == 'POST':
TestFormSet = formset_factory(TestForm)
formset = TestFormSet(request.POST)
if formset.is_valid():
for form in formset:
form.save()
...
else:
TestFormSet = formset_factory(TestForm, extra=0)
initial_list = []
for transaction in transactions:
initial_list.append({'username': transaction.user.username, 'anotherField': transaction.anotherField})
formset = TestFormSet(initial=initial_list)
...
return render(request, .. { .. , 'formList':formset})
如果您的问题是它只显示最后一个表单,则需要查看代码的这一部分。
for transaction in transactions:
form = IndividualSplitTransactionForm(prefix = transaction.user.username)
您在表单变量中保存最后一个表单。所以我认为你可以考虑如下。
formList = []
# make list object with form elements
for transaction in transactions:
form = IndividualSplitTransactionForm()
formList.append(form)
...
# send formList in Context
parameters = {
'record':record,
'formList':formList,
'message':message,
'transactions':transactions,
}
# In your html, you can iterate your formList and show each form.
{% for form in formList %}
{{form}}
{% endfor %}
回答其他问题
我知道表单中有用户名字段。所以我的建议是这样的。
for transaction in transactions:
form = IndividualSplitRansactionFrom(initial={'fieldname which has FK for user instance' : user})
我的想法是你通过设置初始值将用户名值放在表单中。