提前发帖!
这是my previous question的后续内容,其中涉及创建一个将一个表单与每个用户相关联的反馈页面。我能够做到这一点,但它是以我认为是一种被黑客攻击的方式完成的,因为在我提交反馈一次后,我看到了一些非常奇怪的行为。
我们之前没有提交过任何反馈意见,现在我想向三个人中的两个人提交反馈意见(img)。隐藏的management_form详细信息如下所示:
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="3" />
<input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="0" />
<input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000" />
在提交时,这会成功在反馈表中创建两个新条目。问题是,如果我进入任何反馈页面(如同任何用户),我会看到我已经创建的反馈,并且我在提交时会收到错误。
如果我现在转到一个或两个用户的页面,我会看到一个或两个表单(这很好)但是management_form数据不正确。例如,在一个用户页面上,我将看到此management_form数据:
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="3" />
<input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="2" />
<input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000" />
并收到此错误:
MultiValueDictKeyError at /feedback/2/
"u'form-1-id'"
由于我只应该看到一个表格,我所看到的一切,并且它已经设置为已经创建的两个反馈中的第一个,但显然是管理数据的问题。初始值应为0(不是2),总表格应为1(不是3)。
如果我转到具有相同数量用户的页面,我将看到原始的三个反馈表单,并使用此management_form数据:
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="5" />
<input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="2" />
<input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000" />
同样,总数应为3(不是5),初始值应为0(不是2)。这次我没有收到任何错误,因为我会收到一条消息,说我需要填写两个甚至不会出现在页面上的表格的值。
希望能够很好地解释这个问题,所以这里是代码:
models.py
class Feedback(models.Model):
action = models.ForeignKey(Action)
feedback = models.CharField(max_length=1)
feedback_by = models.ForeignKey(UserProfile, related_name='feedback_by')
feedback_for = models.ForeignKey(UserProfile, related_name='feedback_for')
comment = models.CharField(max_length=200)
created = models.DateTimeField()
modified = models.DateTimeField()
def save(self, *args, **kwargs):
if not self.id:
self.created = datetime.datetime.today()
self.modified = datetime.datetime.today()
return super(Feedback, self).save(*args, **kwargs)
forms.py
class FeedbackForm(forms.ModelForm):
choices = (('g', '(+1) Positive'),
('b', '(±0) Negative'),
('n', '(-1) No Show'),
('d', 'Don\'t Leave Feedback'))
feedback = forms.ChoiceField(widget=forms.RadioSelect(), choices=choices, initial='d')
comment = forms.CharField(widget=forms.Textarea())
class Meta:
model = Feedback
fields = ['feedback_for','feedback','comment']
views.py
@login_required
def new_feedback(request, action_id):
action = get_object_or_404(Action, id=action_id)
profile = UserProfile.objects.get(user_id=request.user.id)
participants = all_info_many_profiles(action.participants.filter(~Q(id=profile.id)))
fbformset = modelformset_factory(Feedback, form=FeedbackForm, extra=len(participants))
if request.method == 'POST':
formset = fbformset(request.POST, request.FILES)
if formset.is_valid():
#formset.save(commit=False)
for form in formset:
tmp = form.save(commit=False)
tmp.action = action
tmp.feedback_by = profile
if tmp.feedback != 'd':
tmp.save()
return index(request)
else:
print formset.errors
#return index(request)
else:
formset = fbformset()
return render(request, 'app/new_feedback.html',
{'action': action, 'participants': participants, 'formset': formset}
)
feedback.html
{% load multifor %}
{% block body_block %}
<h1>Leave Feedback</h1>
<form method="post" action="{% url 'app:new_feedback' action.id%}">
{% csrf_token %}
{% comment %}
<input id="id_form-TOTAL_FORMS" name="form-TOTAL_FORMS" type="hidden" value="{{participants.count}}" />
<input id="id_form-INITIAL_FORMS" name="form-INITIAL_FORMS" type="hidden" value="0" />
<input id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS" type="hidden" value="1000" />
{% endcomment %}
{{ formset.management_form }}
{{ formset.errors }}
{% for form in formset; participant in participants %}
{{ form.id }}
{{ form.errors }}
<input id="id_form-{{forloop.counter0}}-feedback_for" name="form-{{forloop.counter0}}-feedback_for" type="hidden" value="{{participant.id}}" /> <br />
{{ form.feedback_for.label }} {{ participant.username }}: <br />
{% for radio in form.feedback %}
{{ radio }} <br />
{% endfor %}<br />
{{ form.comment.label }} {{ form.comment }} <br /><br />
{% endfor %}
<input type="submit" name="submit" value="Submit Feedback" />
</form>
{% endblock %}
答案 0 :(得分:0)
问题是你使用的是modelformset_factory,这个工厂与模型绑定,它会通过填充东西“{3}}来”帮助“你。
您可以使用普通this is why the count is at 5获得所需的结果。 Django的文档有formset_factory