我有Django 1.6应用程序,它将包含一个显示客户列表的表单,其中包含一对" Approve"和"拒绝"每个名称旁边的单选按钮,表示我们是否批准或拒绝其付款方式。我希望每个单选按钮默认设置为"拒绝"首次呈现表单时。我还想要包含一个隐藏的" uid"包含客户用户ID的每一行的字段。当管理员单击每个用户名旁边的“批准”按钮时,他/她想要批准然后提交表单,视图应该读取每个用户的每个隐藏ID值,检查单选按钮,如果用户被批准则更新模型。这是表格的样子:
customer1 (hidden id) [ ] approve [x] reject
customer2 (hidden id) [ ] approve [x] reject
...
customerN (hidden id) [ ] approve [x] reject
我有三个问题,我不太明白如何解决:
我真的很难绕过这些任务。非常感谢你的帮助。
# views.py
def review_payment_methods(request, template):
if request.method == "POST":
payment_method_form = ReviewPaymentMethodForm(request.POST)
if payment_method_form.is_valid():
# How to iterate through form and pull out ids and radio button values??
# Update Account table here
return HttpResponseRedirect('/admin/')
else:
new_accounts = Account.objects.filter(method_approved=False).values()
PaymentMethodFormset = formset_factory(ReviewPaymentMethodForm, extra=new_accounts.count())
formset = PaymentMethodFormset(initial=new_accounts) # This doesn't seem to work
return render_to_response(template, locals(), context_instance=RequestContext(request))
# models.py
class Account(models.Model):
"""A user's account."""
user = models.OneToOneField(User, primary_key=True, unique=True)
method_approved = models.BooleanField(default=False) # This contains Approve/Reject
# forms.py
from django import forms
from django.utils.safestring import mark_safe
class ReviewPaymentMethodForm(forms.Form):
class HorizontalRadioRenderer(forms.RadioSelect.renderer):
def render(self):
return mark_safe(u'\n'.join([u'%s\n' % w for w in self]))
DECISION_CHOICES = (('1', 'Approve'), ('2', 'Reject'))
uid = forms.IntegerField(widget=forms.HiddenInput)
decision = forms.ChoiceField(
choices = DECISION_CHOICES,
widget = forms.RadioSelect(renderer=HorizontalRadioRenderer),
initial = '2', # 1 => Approve, 2 => Reject
)
# review_payment_methods.html
<div class="custom-content">
<h1>Review Payment Methods</h1>
<form action="." method="post">{% csrf_token %}
{% for form in formset %}
{{ form.as_p }}
{% endfor %}
<input type="submit" value="Submit" />
</form>
</div>
答案 0 :(得分:2)
这对于formset来说并不是一项真正的工作。您想要一个带有动态字段集的单个表单;每个字段的名称是客户UID,其值是接受或拒绝。为此,您可以在实例化表单时以编程方式创建字段:
class ReviewPaymentMethodForm(forms.Form):
def __init__(self, *args, **kwargs):
accounts = kwargs.pop('accounts')
super(ReviewPaymentMethodForm, self).__init__(*args, **kwargs)
for account in accounts:
self.fields[str(account.id)] = forms.ChoiceField(
label=account.user.username,
choices=DECISION_CHOICES,
widget=forms.RadioSelect(renderer=HorizontalRadioRenderer),
initial='2', # 1 => Approve, 2 => Reject
)
视图变为:
def review_payment_methods(request, template):
new_accounts = Account.objects.filter(method_approved=False)
if request.method == "POST":
payment_method_form = ReviewPaymentMethodForm(request.POST, accounts=new_accounts)
if payment_method_form.is_valid():
for acc_id, value in payment_method_form.cleaned_data.items():
approved = (value == '1')
Account.objects.filter(pk=acc_id).update(method_approved=approved)
return HttpResponseRedirect('/admin/')
else:
form = ReviewPaymentMethodForm(accounts=new_accounts)
return render(request, template, {'form': form})