清理后的数据仅显示最后的表单集数据
Cleaned data displays only the last formset data
我有一个 django 项目,我在其中使用 django admin 创建仪表板并使用请求库向 API 发出请求。我还使用表单集动态创建多个表单。当我发出 post 请求并使用 ipdb 观察数据时,我发现来自前 n-1 个表单集的数据不在清理后的数据中。仅将来自最后一个表单的数据添加到 json。如何使所有表格中的数据出现在 json 中。这是我的代码,
#forms.py
class CampaignForm(forms.Form):
consumer = forms.CharField(label="Consumer", max_length=200)
startDate = forms.DateTimeField(label="Start Date",
input_formats=['%d/%m/%Y %H:%M'])
endDate = forms.DateTimeField(label="End Date",
input_formats=['%d/%m/%Y %H:%M'])
referreeCredits = forms.IntegerField(label="Referree Credits")
referrerCredits = forms.IntegerField(label="Referrer Credits")
maxReferreeCredits = forms.IntegerField(label="Max Referree Credits")
maxReferrerCredits = forms.IntegerField(label="Max Referrer Credits")
message = forms.CharField(label="Message", max_length=200)
kramerTemplateId = forms.CharField(label="Kramer Template ID", max_length=200)
paymentMode = forms.ChoiceField(label="Payment Mode", choices=[("PAYTM","PAYTM")])
class RuleForm(forms.Form):
eventName = forms.CharField(label="Event Name", max_length=200)
operator = forms.ChoiceField(label="Operator", choices=[("EQUAL","EQUAL"), ("EVERY","EVERY")])
value = forms.IntegerField(label="Value")
class MilestoneRulesForm(forms.Form):
moperator = forms.ChoiceField(label="Operator", choices=[("EQUAL","EQUAL"), ("EVERY","EVERY")])
mvalue = forms.IntegerField(label="Value")
mreferrerCredits = forms.IntegerField(label="Referrer Credits")
Html 模板:
#html
{% block content %}
<div class="form_div" style="width:60%;">
<h2>Campaign Form</h2>
<form method="POST">
{% csrf_token %}
{% for field in form.visible_fields %}
<div class="form-group">
{{ field.label_tag }}
{% render_field field class="form-control" %}
{% if field.help_text %}
<small class="form-text text-muted">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
<div style="display: flex; justify-content: space-between; width: 280px;">
<h3>Rules</h3><button type="button" id="generate-rule" class="btn btn-primary">+</button>
</div>
<div class="parent">
<div>
{{ rule_formset.management_form }}
{% for ruleForm in rule_formset %}
{{ ruleForm.eventName.label}}
{{ ruleForm.eventName }}
{{ ruleForm.operator.label }}
{{ ruleForm.operator }}
{{ ruleForm.value.label }}
{{ ruleForm.value }}
<input type="button" class="btn btn-warn" style="background: red;" value="-">
{% endfor %}
</div>
</div>
<div style="display: flex; justify-content: space-between; width: 280px;">
<h3>Milestone Rules</h3><button type="button" id="generate-milestone-rule" class="btn btn-primary">+</button>
</div>
<div class="milestone-parent">
<div>
{{ milestone_formset.management_form }}
{% for milestoneForm in milestone_formset %}
{{ milestoneForm.moperator.label }}
{{ milestoneForm.moperator }}
{{ milestoneForm.mvalue.label }}
{{ milestoneForm.mvalue }}
{{ milestoneForm.mreferrerCredits.label }}
{{ milestoneForm.mreferrerCredits }}
<input type="button" class="btn btn-warn" style="background: red;" value="-">
{% endfor %}
</div>
</div>
<div>
<input type="submit" value="Post">
</div>
</form>
</div>
<script>
$(function () {
$("#id_startDate").datetimepicker({
format: 'd/m/Y H:i',
});
$("#id_endDate").datetimepicker({
format: 'd/m/Y H:i',
});
});
</script>
<script type='text/javascript'>
const ruleform = `
<div>
<input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS">
<input type="hidden" name="form-INITIAL_FORMS" value="0" 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">
Event Name
<input type="text" name="form-0-eventName" maxlength="200" id="id_form-0-eventName">
Operator
<select name="form-0-operator" id="id_form-0-operator">
<option value="EQUAL">EQUAL</option>
<option value="EVERY">EVERY</option>
</select>
Value
<input type="number" name="form-0-value" id="id_form-0-value">
<input type="button" class="btn btn-warn" style="background: red;" value="-">
</div>
`
const milestoneform = `
<div>
<input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS">
<input type="hidden" name="form-INITIAL_FORMS" value="0" 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">
Operator
<select name="form-0-operator" id="id_form-0-operator">
<option value="EQUAL">EQUAL</option>
<option value="EVERY">EVERY</option>
</select>
Value
<input type="number" name="form-0-value" id="id_form-0-value">
Referrer Credits
<input type="number" name="form-0-referrerCredits" id="id_form-0-referrerCredits">
<input type="button" class="btn btn-warn" style="background: red;" value="-">
</div>
`
$("#generate-rule").on('click', function(e){
$(".parent").append(ruleform)
})
$("#generate-milestone-rule").on('click', function(e){
$(".milestone-parent").append(milestoneform)
})
$(".parent").on("click", (e) => {
return e.target.classList.contains('btn-warn') && e.target.parentNode.remove()
})
$(".milestone-parent").on("click", (e) => {
return e.target.classList.contains('btn-warn') && e.target.parentNode.remove()
})
</script>
{% endblock %}
views.py:
def campaign_add(self, request):
form = CampaignForm()
RuleFormSet = formset_factory(RuleForm)
MilestoneFormSet = formset_factory(MilestoneRulesForm)
if request.method == 'POST':
# import ipdb; ipdb.set_trace()
form = CampaignForm(request.POST)
rule_formset = RuleFormSet(request.POST)
milestone_formset = MilestoneFormSet(request.POST)
if form.is_valid() and rule_formset.is_valid() and milestone_formset.is_valid():
import ipdb; ipdb.set_trace()
# <QueryDict: {'csrfmiddlewaretoken': ['q9Ox6KtEWUxIFXm305KhGRlHcliXtIgc6AjjqjkhG7p791tKvILMXZh8yZdWJWSW'], 'consumer': ['FILING'], 'startDate': ['05/04/2019 16:28'], 'endDate': ['06/04/2019 16:28'], 'referreeCredits': ['50'], 'referrerCredits': ['50'], 'maxReferreeCredits': ['50'], 'maxReferrerCredits': ['50'], 'message': ['Hello'], 'kramerTemplateId': ['kt01'], 'paymentMode': ['PAYTM'], 'form-TOTAL_FORMS': ['1', '1'], 'form-INITIAL_FORMS': ['0', '0'], 'form-MIN_NUM_FORMS': ['0', '0'], 'form-MAX_NUM_FORMS': ['1000', '1000'], 'form-0-eventName': ['string'], 'form-0-operator': ['EQUAL'], 'form-0-value': ['0'], 'form-0-moperator': ['EQUAL'], 'form-0-mvalue': ['0'], 'form-0-mreferrerCredits': ['50']}>
dat = {}
dat["consumer"] = form.cleaned_data["consumer"]
dat["startDate"] = self.datetime_to_epoch(form.cleaned_data["startDate"])
dat["endDate"] = self.datetime_to_epoch(form.cleaned_data["endDate"])
dat["referreeCredits"] = form.cleaned_data["referreeCredits"]
dat["referrerCredits"] = form.cleaned_data["referrerCredits"]
dat["maxReferreeCredits"] = form.cleaned_data["maxReferreeCredits"]
dat["maxReferrerCredits"] = form.cleaned_data["maxReferrerCredits"]
dat["message"] = form.cleaned_data["message"]
dat["kramerTemplateId"] = form.cleaned_data["kramerTemplateId"]
dat["paymentMode"] = form.cleaned_data["paymentMode"]
arrRules = rule_formset.cleaned_data
arrMilestoneRules = milestone_formset.cleaned_data
dat["eventRules"] = arrRules
dat["milestoneRules"] = arrMilestoneRules
print(dat)
res = requests.post("https://example.com", data=json.dumps(dat), headers={'content-type': 'application/json'})
if res.status_code == 201 or res.status_code == 200:
messages.success(request, 'Success!')
return redirect("admin:campaign-pg1")
else:
messages.error(request, 'Submission Failed.')
else:
rule_formset = RuleFormSet()
milestone_formset = MilestoneFormSet()
return TemplateResponse(request, "admin/campaign_add.html", {"form":form, "rule_formset": rule_formset, "milestone_formset": milestone_formset})
来自request.POST的数据:
<QueryDict: {'csrfmiddlewaretoken': ['LV5T8pd2DCileU9XFAdPwR23zbVn3sO8rmAFsY4FnPaKIYgEadekNZYuVPQmjGqS'], 'consumer': ['sx'], 'startDate': ['06/04/2019 17:40'], 'endDate': ['05/04/2019 19:00'], 'referreeCredits': ['23'], 'referrerCredits': ['22'], 'maxReferreeCredits': ['33'], 'maxReferrerCredits': ['1'], 'message': ['sdsd'], 'kramerTemplateId': ['kt01'], 'paymentMode': ['PAYTM'], 'form-TOTAL_FORMS': ['1', '1', '1'], 'form-INITIAL_FORMS': ['0', '0', '0'], 'form-MIN_NUM_FORMS': ['0', '0', '0'], 'form-MAX_NUM_FORMS': ['1000', '1000', '1000'], 'form-0-eventName': ['string', 'string2'], 'form-0-operator': ['EQUAL', 'EVERY'], 'form-0-value': ['3', '0'], 'form-0-moperator': ['EQUAL'], 'form-0-mvalue': ['3'], 'form-0-mreferrerCredits': ['4']}>
清理数据中的数据:
{'consumer': 'sx', 'startDate': 1554552600.0, 'endDate': 1554471000.0, 'referreeCredits': 23, 'referrerCredits': 22, 'maxReferreeCredits': 33, 'maxReferrerCredits': 1, 'message': 'sdsd', 'kramerTemplateId': 'kt01', 'paymentMode': 'PAYTM', 'eventRules': [{'eventName': 'string2', 'operator': 'EVERY', 'value': 0}], 'milestoneRules': [{'moperator': 'EQUAL', 'mvalue': 3, 'mreferrerCredits': 4}]}
注意:eventRules中应该有两个字典(两种形式)的数据。仅显示一本词典。
为什么会这样?我能做什么?
编辑1:
这是我在实施@pedro 的回答后得到的 request.POST,
<QueryDict: {'csrfmiddlewaretoken': ['TqrjQp6mpuKaCRMcJtAq2ihxiLLtaEFrzRW5aYXZ9HCz6VTTe6BVjqdYEpGsqShb'], 'consumer': ['FILING'], 'startDate': ['05/04/2019 16:28'], 'endDate': ['06/04/2019 16:28'], 'referreeCredits': ['50'], 'referrerCredits': ['50'], 'maxReferreeCredits': ['50'], 'maxReferrerCredits': ['50'], 'message': ['Hello'], 'kramerTemplateId': ['kt01'], 'paymentMode': ['PAYTM'], 'form-TOTAL_FORMS': ['1', '1'], 'form-INITIAL_FORMS': ['0', '0'], 'form-MIN_NUM_FORMS': ['0', '0'], 'form-MAX_NUM_FORMS': ['1000', '1000'], 'form-0-eventName': ['string'], 'form-0-operator': ['EQUAL'], 'form-0-value': ['0'], 'form-{n}-eventName': ['string2'], 'form-{n}-operator': ['EVERY', 'EVERY'], 'form-{n}-value': ['1', '1'], 'form-0-moperator': ['EQUAL'], 'form-0-mvalue': ['1'], 'form-0-mreferrerCredits': ['50'], 'form-{n}-mReferrerCredits': ['20']}>
JavaScript错误
$("#generate-rule").on('click', function(e){
var n = $("#id_form-TOTAL_FORMS").value; // current number of forms;
var new_form = ruleform.replace(/{n}/g, n); // replace all {n} by the new form number
$(".parent").append(new_form);
$("#id_form-TOTAL_FORMS").value = parseInt(n) + 1; // update the total forms number
console.log(n);
})
$("#id_form-TOTAL_FORMS").value 返回未定义
编辑2:
我现在收到这个错误 -
Internal Server Error: /admin/campaign/add
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.7/site-packages/django/utils/decorators.py", line 142, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/contrib/admin/sites.py", line 223, in inner
return view(request, *args, **kwargs)
File "/Users/mohnishmallya/Desktop/Projects/campaign_dashboard/Referralapp/refapp/admin.py", line 50, in campaign_add
if form.is_valid() and rule_formset.is_valid() and milestone_formset.is_valid():
File "/usr/local/lib/python3.7/site-packages/django/forms/formsets.py", line 301, in is_valid
self.errors
File "/usr/local/lib/python3.7/site-packages/django/forms/formsets.py", line 281, in errors
self.full_clean()
File "/usr/local/lib/python3.7/site-packages/django/forms/formsets.py", line 322, in full_clean
for i in range(0, self.total_form_count()):
File "/usr/local/lib/python3.7/site-packages/django/forms/formsets.py", line 110, in total_form_count
return min(self.management_form.cleaned_data[TOTAL_FORM_COUNT], self.absolute_max)
File "/usr/local/lib/python3.7/site-packages/django/utils/functional.py", line 37, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/usr/local/lib/python3.7/site-packages/django/forms/formsets.py", line 92, in management_form
code='missing_management_form',
django.core.exceptions.ValidationError: ['ManagementForm data is missing or has been tampered with']
在我看来这一行-
如果 form.is_valid() 和 rule_formset.is_valid() 和 milestone_formset.is_valid():
我也稍微更改了我的 html 模板代码
<div style="display: flex; justify-content: space-between; width: 280px;">
<h3>Rules</h3>
<button type="button" id="generate-rule" class="btn btn-primary">+</button>
</div>
<div class="parent">
<div>
{{ rule_formset.management_form }}
{% for ruleForm in rule_formset %}
{{ ruleForm }}
<input type="button" class="btn btn-warn" style="background: red;" value="-">
{% endfor %}
</div>
</div>
<div style="display: flex; justify-content: space-between; width: 280px;">
<h3>Milestone Rules</h3>
<button type="button" id="generate-milestone-rule" class="btn btn-primary">+</button>
</div>
<div class="milestone-parent">
<div>
{{ milestone_formset.management_form }}
{% for milestoneForm in milestone_formset %}
{{ milestoneForm }}
<input type="button" class="btn btn-warn" style="background: red;" value="-">
{% endfor %}
</div>
</div>
问题出在你的javascript,你应该只有一个这样的输入:
<input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS">
<input type="hidden" name="form-INITIAL_FORMS" value="0" 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">
但是您在 javascript 变量 ruleform
和 milestoneform
中复制了它们。当您添加新表单时,您必须更新输入 form-TOTAL_FORMS
的值,这是 ruleform
的示例,您必须对 milestoneform
:
执行相同的操作
const ruleform = `
<div>
Event Name
<input type="text" name="form-{n}-eventName" maxlength="200" id="id_form-{n}-eventName">
Operator
<select name="form-{n}-operator" id="id_form-{n}-operator">
<option value="EQUAL">EQUAL</option>
<option value="EVERY">EVERY</option>
</select>
Value
<input type="number" name="form-{n}-value" id="id_form-{n}-value">
<input type="button" class="btn btn-warn" style="background: red;" value="-">
</div>
`
$("#generate-rule").on('click', function(e){
var n = $("#id_form-TOTAL_FORMS").val(); // current number of forms;
var new_form = ruleform.replace(/{n}/g, n); // replace all {n} by the new form number
$(".parent").append(new_form);
$("#id_form-TOTAL_FORMS").val(parseInt(n) + 1); // update the total forms number
})
当您处理表单集时,所有表单都需要有不同的编号,这就是为什么我将 0
替换为 ruleform
中的 {n}
。我不确定我是否遗漏了什么,但希望这能让你知道你需要做什么。
我有一个 django 项目,我在其中使用 django admin 创建仪表板并使用请求库向 API 发出请求。我还使用表单集动态创建多个表单。当我发出 post 请求并使用 ipdb 观察数据时,我发现来自前 n-1 个表单集的数据不在清理后的数据中。仅将来自最后一个表单的数据添加到 json。如何使所有表格中的数据出现在 json 中。这是我的代码,
#forms.py
class CampaignForm(forms.Form):
consumer = forms.CharField(label="Consumer", max_length=200)
startDate = forms.DateTimeField(label="Start Date",
input_formats=['%d/%m/%Y %H:%M'])
endDate = forms.DateTimeField(label="End Date",
input_formats=['%d/%m/%Y %H:%M'])
referreeCredits = forms.IntegerField(label="Referree Credits")
referrerCredits = forms.IntegerField(label="Referrer Credits")
maxReferreeCredits = forms.IntegerField(label="Max Referree Credits")
maxReferrerCredits = forms.IntegerField(label="Max Referrer Credits")
message = forms.CharField(label="Message", max_length=200)
kramerTemplateId = forms.CharField(label="Kramer Template ID", max_length=200)
paymentMode = forms.ChoiceField(label="Payment Mode", choices=[("PAYTM","PAYTM")])
class RuleForm(forms.Form):
eventName = forms.CharField(label="Event Name", max_length=200)
operator = forms.ChoiceField(label="Operator", choices=[("EQUAL","EQUAL"), ("EVERY","EVERY")])
value = forms.IntegerField(label="Value")
class MilestoneRulesForm(forms.Form):
moperator = forms.ChoiceField(label="Operator", choices=[("EQUAL","EQUAL"), ("EVERY","EVERY")])
mvalue = forms.IntegerField(label="Value")
mreferrerCredits = forms.IntegerField(label="Referrer Credits")
Html 模板:
#html
{% block content %}
<div class="form_div" style="width:60%;">
<h2>Campaign Form</h2>
<form method="POST">
{% csrf_token %}
{% for field in form.visible_fields %}
<div class="form-group">
{{ field.label_tag }}
{% render_field field class="form-control" %}
{% if field.help_text %}
<small class="form-text text-muted">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
<div style="display: flex; justify-content: space-between; width: 280px;">
<h3>Rules</h3><button type="button" id="generate-rule" class="btn btn-primary">+</button>
</div>
<div class="parent">
<div>
{{ rule_formset.management_form }}
{% for ruleForm in rule_formset %}
{{ ruleForm.eventName.label}}
{{ ruleForm.eventName }}
{{ ruleForm.operator.label }}
{{ ruleForm.operator }}
{{ ruleForm.value.label }}
{{ ruleForm.value }}
<input type="button" class="btn btn-warn" style="background: red;" value="-">
{% endfor %}
</div>
</div>
<div style="display: flex; justify-content: space-between; width: 280px;">
<h3>Milestone Rules</h3><button type="button" id="generate-milestone-rule" class="btn btn-primary">+</button>
</div>
<div class="milestone-parent">
<div>
{{ milestone_formset.management_form }}
{% for milestoneForm in milestone_formset %}
{{ milestoneForm.moperator.label }}
{{ milestoneForm.moperator }}
{{ milestoneForm.mvalue.label }}
{{ milestoneForm.mvalue }}
{{ milestoneForm.mreferrerCredits.label }}
{{ milestoneForm.mreferrerCredits }}
<input type="button" class="btn btn-warn" style="background: red;" value="-">
{% endfor %}
</div>
</div>
<div>
<input type="submit" value="Post">
</div>
</form>
</div>
<script>
$(function () {
$("#id_startDate").datetimepicker({
format: 'd/m/Y H:i',
});
$("#id_endDate").datetimepicker({
format: 'd/m/Y H:i',
});
});
</script>
<script type='text/javascript'>
const ruleform = `
<div>
<input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS">
<input type="hidden" name="form-INITIAL_FORMS" value="0" 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">
Event Name
<input type="text" name="form-0-eventName" maxlength="200" id="id_form-0-eventName">
Operator
<select name="form-0-operator" id="id_form-0-operator">
<option value="EQUAL">EQUAL</option>
<option value="EVERY">EVERY</option>
</select>
Value
<input type="number" name="form-0-value" id="id_form-0-value">
<input type="button" class="btn btn-warn" style="background: red;" value="-">
</div>
`
const milestoneform = `
<div>
<input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS">
<input type="hidden" name="form-INITIAL_FORMS" value="0" 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">
Operator
<select name="form-0-operator" id="id_form-0-operator">
<option value="EQUAL">EQUAL</option>
<option value="EVERY">EVERY</option>
</select>
Value
<input type="number" name="form-0-value" id="id_form-0-value">
Referrer Credits
<input type="number" name="form-0-referrerCredits" id="id_form-0-referrerCredits">
<input type="button" class="btn btn-warn" style="background: red;" value="-">
</div>
`
$("#generate-rule").on('click', function(e){
$(".parent").append(ruleform)
})
$("#generate-milestone-rule").on('click', function(e){
$(".milestone-parent").append(milestoneform)
})
$(".parent").on("click", (e) => {
return e.target.classList.contains('btn-warn') && e.target.parentNode.remove()
})
$(".milestone-parent").on("click", (e) => {
return e.target.classList.contains('btn-warn') && e.target.parentNode.remove()
})
</script>
{% endblock %}
views.py:
def campaign_add(self, request):
form = CampaignForm()
RuleFormSet = formset_factory(RuleForm)
MilestoneFormSet = formset_factory(MilestoneRulesForm)
if request.method == 'POST':
# import ipdb; ipdb.set_trace()
form = CampaignForm(request.POST)
rule_formset = RuleFormSet(request.POST)
milestone_formset = MilestoneFormSet(request.POST)
if form.is_valid() and rule_formset.is_valid() and milestone_formset.is_valid():
import ipdb; ipdb.set_trace()
# <QueryDict: {'csrfmiddlewaretoken': ['q9Ox6KtEWUxIFXm305KhGRlHcliXtIgc6AjjqjkhG7p791tKvILMXZh8yZdWJWSW'], 'consumer': ['FILING'], 'startDate': ['05/04/2019 16:28'], 'endDate': ['06/04/2019 16:28'], 'referreeCredits': ['50'], 'referrerCredits': ['50'], 'maxReferreeCredits': ['50'], 'maxReferrerCredits': ['50'], 'message': ['Hello'], 'kramerTemplateId': ['kt01'], 'paymentMode': ['PAYTM'], 'form-TOTAL_FORMS': ['1', '1'], 'form-INITIAL_FORMS': ['0', '0'], 'form-MIN_NUM_FORMS': ['0', '0'], 'form-MAX_NUM_FORMS': ['1000', '1000'], 'form-0-eventName': ['string'], 'form-0-operator': ['EQUAL'], 'form-0-value': ['0'], 'form-0-moperator': ['EQUAL'], 'form-0-mvalue': ['0'], 'form-0-mreferrerCredits': ['50']}>
dat = {}
dat["consumer"] = form.cleaned_data["consumer"]
dat["startDate"] = self.datetime_to_epoch(form.cleaned_data["startDate"])
dat["endDate"] = self.datetime_to_epoch(form.cleaned_data["endDate"])
dat["referreeCredits"] = form.cleaned_data["referreeCredits"]
dat["referrerCredits"] = form.cleaned_data["referrerCredits"]
dat["maxReferreeCredits"] = form.cleaned_data["maxReferreeCredits"]
dat["maxReferrerCredits"] = form.cleaned_data["maxReferrerCredits"]
dat["message"] = form.cleaned_data["message"]
dat["kramerTemplateId"] = form.cleaned_data["kramerTemplateId"]
dat["paymentMode"] = form.cleaned_data["paymentMode"]
arrRules = rule_formset.cleaned_data
arrMilestoneRules = milestone_formset.cleaned_data
dat["eventRules"] = arrRules
dat["milestoneRules"] = arrMilestoneRules
print(dat)
res = requests.post("https://example.com", data=json.dumps(dat), headers={'content-type': 'application/json'})
if res.status_code == 201 or res.status_code == 200:
messages.success(request, 'Success!')
return redirect("admin:campaign-pg1")
else:
messages.error(request, 'Submission Failed.')
else:
rule_formset = RuleFormSet()
milestone_formset = MilestoneFormSet()
return TemplateResponse(request, "admin/campaign_add.html", {"form":form, "rule_formset": rule_formset, "milestone_formset": milestone_formset})
来自request.POST的数据:
<QueryDict: {'csrfmiddlewaretoken': ['LV5T8pd2DCileU9XFAdPwR23zbVn3sO8rmAFsY4FnPaKIYgEadekNZYuVPQmjGqS'], 'consumer': ['sx'], 'startDate': ['06/04/2019 17:40'], 'endDate': ['05/04/2019 19:00'], 'referreeCredits': ['23'], 'referrerCredits': ['22'], 'maxReferreeCredits': ['33'], 'maxReferrerCredits': ['1'], 'message': ['sdsd'], 'kramerTemplateId': ['kt01'], 'paymentMode': ['PAYTM'], 'form-TOTAL_FORMS': ['1', '1', '1'], 'form-INITIAL_FORMS': ['0', '0', '0'], 'form-MIN_NUM_FORMS': ['0', '0', '0'], 'form-MAX_NUM_FORMS': ['1000', '1000', '1000'], 'form-0-eventName': ['string', 'string2'], 'form-0-operator': ['EQUAL', 'EVERY'], 'form-0-value': ['3', '0'], 'form-0-moperator': ['EQUAL'], 'form-0-mvalue': ['3'], 'form-0-mreferrerCredits': ['4']}>
清理数据中的数据:
{'consumer': 'sx', 'startDate': 1554552600.0, 'endDate': 1554471000.0, 'referreeCredits': 23, 'referrerCredits': 22, 'maxReferreeCredits': 33, 'maxReferrerCredits': 1, 'message': 'sdsd', 'kramerTemplateId': 'kt01', 'paymentMode': 'PAYTM', 'eventRules': [{'eventName': 'string2', 'operator': 'EVERY', 'value': 0}], 'milestoneRules': [{'moperator': 'EQUAL', 'mvalue': 3, 'mreferrerCredits': 4}]}
注意:eventRules中应该有两个字典(两种形式)的数据。仅显示一本词典。
为什么会这样?我能做什么?
编辑1: 这是我在实施@pedro 的回答后得到的 request.POST,
<QueryDict: {'csrfmiddlewaretoken': ['TqrjQp6mpuKaCRMcJtAq2ihxiLLtaEFrzRW5aYXZ9HCz6VTTe6BVjqdYEpGsqShb'], 'consumer': ['FILING'], 'startDate': ['05/04/2019 16:28'], 'endDate': ['06/04/2019 16:28'], 'referreeCredits': ['50'], 'referrerCredits': ['50'], 'maxReferreeCredits': ['50'], 'maxReferrerCredits': ['50'], 'message': ['Hello'], 'kramerTemplateId': ['kt01'], 'paymentMode': ['PAYTM'], 'form-TOTAL_FORMS': ['1', '1'], 'form-INITIAL_FORMS': ['0', '0'], 'form-MIN_NUM_FORMS': ['0', '0'], 'form-MAX_NUM_FORMS': ['1000', '1000'], 'form-0-eventName': ['string'], 'form-0-operator': ['EQUAL'], 'form-0-value': ['0'], 'form-{n}-eventName': ['string2'], 'form-{n}-operator': ['EVERY', 'EVERY'], 'form-{n}-value': ['1', '1'], 'form-0-moperator': ['EQUAL'], 'form-0-mvalue': ['1'], 'form-0-mreferrerCredits': ['50'], 'form-{n}-mReferrerCredits': ['20']}>
JavaScript错误
$("#generate-rule").on('click', function(e){
var n = $("#id_form-TOTAL_FORMS").value; // current number of forms;
var new_form = ruleform.replace(/{n}/g, n); // replace all {n} by the new form number
$(".parent").append(new_form);
$("#id_form-TOTAL_FORMS").value = parseInt(n) + 1; // update the total forms number
console.log(n);
})
$("#id_form-TOTAL_FORMS").value 返回未定义
编辑2: 我现在收到这个错误 -
Internal Server Error: /admin/campaign/add
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.7/site-packages/django/utils/decorators.py", line 142, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/contrib/admin/sites.py", line 223, in inner
return view(request, *args, **kwargs)
File "/Users/mohnishmallya/Desktop/Projects/campaign_dashboard/Referralapp/refapp/admin.py", line 50, in campaign_add
if form.is_valid() and rule_formset.is_valid() and milestone_formset.is_valid():
File "/usr/local/lib/python3.7/site-packages/django/forms/formsets.py", line 301, in is_valid
self.errors
File "/usr/local/lib/python3.7/site-packages/django/forms/formsets.py", line 281, in errors
self.full_clean()
File "/usr/local/lib/python3.7/site-packages/django/forms/formsets.py", line 322, in full_clean
for i in range(0, self.total_form_count()):
File "/usr/local/lib/python3.7/site-packages/django/forms/formsets.py", line 110, in total_form_count
return min(self.management_form.cleaned_data[TOTAL_FORM_COUNT], self.absolute_max)
File "/usr/local/lib/python3.7/site-packages/django/utils/functional.py", line 37, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/usr/local/lib/python3.7/site-packages/django/forms/formsets.py", line 92, in management_form
code='missing_management_form',
django.core.exceptions.ValidationError: ['ManagementForm data is missing or has been tampered with']
在我看来这一行-
如果 form.is_valid() 和 rule_formset.is_valid() 和 milestone_formset.is_valid():
我也稍微更改了我的 html 模板代码
<div style="display: flex; justify-content: space-between; width: 280px;">
<h3>Rules</h3>
<button type="button" id="generate-rule" class="btn btn-primary">+</button>
</div>
<div class="parent">
<div>
{{ rule_formset.management_form }}
{% for ruleForm in rule_formset %}
{{ ruleForm }}
<input type="button" class="btn btn-warn" style="background: red;" value="-">
{% endfor %}
</div>
</div>
<div style="display: flex; justify-content: space-between; width: 280px;">
<h3>Milestone Rules</h3>
<button type="button" id="generate-milestone-rule" class="btn btn-primary">+</button>
</div>
<div class="milestone-parent">
<div>
{{ milestone_formset.management_form }}
{% for milestoneForm in milestone_formset %}
{{ milestoneForm }}
<input type="button" class="btn btn-warn" style="background: red;" value="-">
{% endfor %}
</div>
</div>
问题出在你的javascript,你应该只有一个这样的输入:
<input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS">
<input type="hidden" name="form-INITIAL_FORMS" value="0" 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">
但是您在 javascript 变量 ruleform
和 milestoneform
中复制了它们。当您添加新表单时,您必须更新输入 form-TOTAL_FORMS
的值,这是 ruleform
的示例,您必须对 milestoneform
:
const ruleform = `
<div>
Event Name
<input type="text" name="form-{n}-eventName" maxlength="200" id="id_form-{n}-eventName">
Operator
<select name="form-{n}-operator" id="id_form-{n}-operator">
<option value="EQUAL">EQUAL</option>
<option value="EVERY">EVERY</option>
</select>
Value
<input type="number" name="form-{n}-value" id="id_form-{n}-value">
<input type="button" class="btn btn-warn" style="background: red;" value="-">
</div>
`
$("#generate-rule").on('click', function(e){
var n = $("#id_form-TOTAL_FORMS").val(); // current number of forms;
var new_form = ruleform.replace(/{n}/g, n); // replace all {n} by the new form number
$(".parent").append(new_form);
$("#id_form-TOTAL_FORMS").val(parseInt(n) + 1); // update the total forms number
})
当您处理表单集时,所有表单都需要有不同的编号,这就是为什么我将 0
替换为 ruleform
中的 {n}
。我不确定我是否遗漏了什么,但希望这能让你知道你需要做什么。