gpt4 book ai didi

python - 手动填充 modelformset Django 进行测试

转载 作者:太空宇宙 更新时间:2023-11-04 04:26:05 25 4
gpt4 key购买 nike

我遇到错误 django.forms.utils.ValidationError: ['ManagementForm data is missing or has been tampered with'],但它只发生在测试我的代码时。当使用真正的 POST 请求呈现实际网页时,它不会抛出此错误。

我有一个名为 Position 的模型,表单集由其候选对象组成。所以对于一个特定的职位,我可能有 4 个候选人。

模型.py

class Candidate(models.Model):
user = models.ForeignKey(User, related_name="candidate")
votes = models.PositiveIntegerField(verbose_name="Antall stemmer", blank=True, default=0)


class Position(models.Model):
# Candidates running for position
candidates = models.ManyToManyField(Candidate, blank=True, related_name="positions")

# Number of people voting
number_of_voters = models.PositiveIntegerField(default=0, verbose_name="Antall stemmesedler avgitt")

表单.py

class AddPrevoteForm(forms.ModelForm):
class Meta:
model = Position
fields = ['number_of_voters']


class AddPreVoteToCandidateForm(forms.ModelForm):
class Meta:
model = Candidate
fields = ['votes']

def __init__(self, *args, **kwargs):
super(AddPreVoteToCandidateForm, self).__init__(*args, **kwargs)
self.fields['votes'].label = self.instance.user.get_full_name()

View .py

@permission_required('elections.add_election')
@login_required
def admin_register_prevotes(request, pk):
# Fetch position
position = get_object_or_404(Position, pk=pk)
# For for editing total number of people prevoting
prevote_form = AddPrevoteForm(request.POST or None, instance=position)
# Form for adjusting individual candidate's votes
CandidateFormSet = modelformset_factory(
Candidate, form=AddPreVoteToCandidateForm, extra=0
)
formset = CandidateFormSet(
request.POST or None,
queryset=position.candidates.all()
)
if request.method == 'POST':
if formset.is_valid() and prevote_form.is_valid():
for form in formset:
# Increment both candidate and positions votes
candidate_pk = form.instance.pk
candidate = Candidate.objects.get(pk=candidate_pk)
old_votes = candidate.votes
new_votes = form.cleaned_data['votes']
position.total_votes += (new_votes - old_votes)
form.save()
prevote_form.save()
return redirect(reverse(
'elections:admin_register_candidates',
kwargs={'pk': position.id}
))
context = {
'prevote_form': prevote_form,
'candidate_formset': formset,
'position': position
}
return render(
request, 'elections/admin/admin_add_prevotes.html',
context
)

和模板

<form method="POST">{% csrf_token %}
{{ candidate_formset.management_form }}
{% for candidate_form in candidate_formset %}
<div>
{{ candidate_form }}
</div>
{% endfor %}
{{ prevote_form }}
<div>
<input class="button is-success" type="submit" value="Add prevotes!"></input>
</div>
</form>

来自模板的结果 formset 如下所示:

<input type="hidden" name="form-TOTAL_FORMS" value="4" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="4" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS" />
<tr><th><label for="id_form-0-votes">Sindre Bakke:</label></th><td><input type="number" name="form-0-votes" value="3" min="0" id="id_form-0-votes" /><input type="hidden" name="form-0-id" value="1" id="id_form-0-id" /></td></tr> <tr><th><label for="id_form-1-votes">Christopher Massey:</label></th><td><input type="number" name="form-1-votes" value="2" min="0" id="id_form-1-votes" /><input type="hidden" name="form-1-id" value="2" id="id_form-1-id" /></td></tr> <tr><th><label for="id_form-2-votes">Ann Green:</label></th><td><input type="number" name="form-2-votes" value="0" min="0" id="id_form-2-votes" /><input type="hidden" name="form-2-id" value="3" id="id_form-2-id" /></td></tr> <tr><th><label for="id_form-3-votes">Michelle Murray:</label></th><td><input type="number" name="form-3-votes" value="0" min="0" id="id_form-3-votes" /><input type="hidden" name="form-3-id" value="4" id="id_form-3-id" /></td></tr>

这就是我尝试以下测试的原因(post_data 中的前四个来自 management_form)

@pytest.mark.django_db
def test_add_pre_votes_to_candidate(
client, create_admin_user,
create_open_election_with_position_and_candidates):
admin = create_admin_user
client.login(username=admin.username, password='defaultpassword')
election = create_open_election_with_position_and_candidates
position = election.positions.all().first()
number_of_candidates = position.candidates.all().count()
candidate = position.candidates.all().first()
post_data = {
'form-TOTAL_FORMS:': '4',
'form-INITIAL_FORMS': '4',
'form-MIN_NUM_FORMS': '0',
'form-MAX_NUM_FORMS': '1000',
'form-0-votes': '3',
'form-0-id': 1,
'form-1-votes': '2',
'form-1-id': 2,
'form-2-votes': '0',
'form-2-id': 3,
'form-3-votes': '0',
'form-3-id': 4,
'number_of_voters': '0'
}
client.post(
reverse(
'elections:admin_register_prevotes',
kwargs={'pk': position.id}
),
data=post_data
)

如有任何帮助,我们将不胜感激!

最佳答案

这通常是由于管理表单存在一些问题。post_data 中似乎有错字, 'form-TOTAL_FORMS:'有一个额外的 :在字符串的末尾。

此外,请注意单元测试中的隐式主键。取决于提供 Candidates 的固定装置的实现对象,它们在数据库中的 ID 可能并不总是从 1,2,.. 等开始。

关于python - 手动填充 modelformset Django 进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53466445/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com