Django:第一次提交后的奇怪表单集行为

2024-04-24 10:36:19 发布

您现在位置:Python中文网/ 问答频道 /正文

前面有长柱!在

这是my previous question的后续操作,它是关于创建一个将一个表单与每个用户关联的反馈页面。我能够做到这一点,但它是以一种黑客的方式完成的,因为我在提交一次反馈后看到了一些非常奇怪的行为。在

假设我以前没有提交任何反馈,现在我想为三个人中的两个人(img)提交反馈。隐藏的管理表单详细信息如下所示:

<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" />

提交后,它成功地在反馈表中创建了两个新条目。问题是现在如果我进入任何反馈页面(作为任何用户),我会看到我已经创建的反馈,并且在提交时会出现错误。在

如果我现在转到一个有一两个用户的页面,我会看到一个或两个表单(这很好),但是管理表单数据不正确。例如,在单用户页面上,我将看到以下管理表单数据:

^{pr2}$

得到这个错误:

MultiValueDictKeyError at /feedback/2/
"u'form-1-id'"

因为我应该只显示一个表单,这就是我所看到的,它被设置为已经创建的两个反馈中的第一个,但是管理数据显然有问题。初始值应为0(不是2),总计形式应为1(不是3)。在

如果我进入一个用户数相等的页面,我会看到原始的三个反馈表,其中包含以下管理表单数据:

<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)。但这次我没有收到错误,因为我会收到一条消息,说我需要为两个甚至没有出现在页面上的表单填写值。在

希望这能很好地解释问题,下面是代码:

在模型.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)

在表单.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']

在视图.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}
                  )

在反馈.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 %}

Tags: nameformid表单forinputvaluemodels
1条回答
网友
1楼 · 发布于 2024-04-24 10:36:19

问题是您使用的是modelformset工厂,这个工厂与模型绑定在一起,它将通过填充内容this is why the count is at 5来“帮助”您。在

您可以通过使用普通的formset_factory获得所需的结果。Django的文档有some examples

相关问题 更多 >