【发布时间】:2020-01-10 08:50:15
【问题描述】:
我在一个模板中显示一个表单和一个表单集,并尝试保存它们。 Formset 可以很好地保存,但是当我添加表单时,它会给出 'NoneType' object is not iterable 错误。
Django 显示我在这个阶段出错,Chrome 显示我的变量如下。
问题行:po = purchaseorder_form.save()
▼ 局部变量
ProductBatchFormset <"class 'django.forms.formsets.ProductBatchFormFormSet'>
productbatch_formset <"django.forms.formsets.ProductBatchFormFormSet object at 0x10bc39950">
purchaseorder_form <"PurchaseOrderForm bound=True, valid=True, fields=(purchaseOrderId;issuedBy;issuedAt;issuedTo;referencePurchaseOrders;internalManager;note;productSpendType)">
request <"WSGIRequest: POST '/purchaseorder/create?submitted=True'">
submitted False
完整追溯
Traceback (most recent call last):
File "/Users/marinalee/.local/share/virtualenvs/scm-SrDaDYy6/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/Users/marinalee/.local/share/virtualenvs/scm-SrDaDYy6/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/marinalee/.local/share/virtualenvs/scm-SrDaDYy6/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/marinalee/django-projects/scm/purchaseorders/views.py", line 22, in create_purchaseOrder
po = purchaseorder_form.save()
File "/Users/marinalee/.local/share/virtualenvs/scm-SrDaDYy6/lib/python3.7/site-packages/django/forms/models.py", line 459, in save
self._save_m2m()
File "/Users/marinalee/.local/share/virtualenvs/scm-SrDaDYy6/lib/python3.7/site-packages/django/forms/models.py", line 441, in _save_m2m
f.save_form_data(self.instance, cleaned_data[f.name])
File "/Users/marinalee/.local/share/virtualenvs/scm-SrDaDYy6/lib/python3.7/site-packages/django/db/models/fields/related.py", line 1621, in save_form_data
getattr(instance, self.attname).set(data)
File "/Users/marinalee/.local/share/virtualenvs/scm-SrDaDYy6/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py", line 975, in set
objs = tuple(objs)
TypeError: 'NoneType' object is not iterable
# forms.py
class PurchaseOrderForm(forms.ModelForm):
class Meta:
model = PurchaseOrder
fields = '__all__'
issuedAt = forms.DateField(
widget=forms.DateInput(format='%Y%m%d', attrs={'placeholder': 'YYYYMMDD'}),
input_formats=('%Y%m%d', )
)
referencePurchaseOrders = forms.ModelChoiceField(widget=forms.SelectMultiple, queryset=PurchaseOrder.objects.all(), required=False)
internalManager = forms.ModelChoiceField(queryset=CustomUser.objects.all(), required=False)
issuedBy = forms.ModelChoiceField(queryset=Company.objects.all(), required=False)
issuedTo = forms.ModelChoiceField(queryset=Company.objects.all(), required=False)
productSpendType = forms.ModelChoiceField(queryset=ProductSpendType.objects.all(), required=False)
class ProductBatchForm(forms.ModelForm):
class Meta:
model = ProductBatch
fields = '__all__'
product = forms.ModelChoiceField(queryset=Product.objects.all(), required=False)
quantity = forms.CharField(required=False)
unitprice = forms.CharField(required=False)
unitcurrency = forms.ModelChoiceField(queryset=Currency.objects.all(), required=False)
productSpendType = forms.ModelChoiceField(queryset=ProductSpendType.objects.all(), required=False)
# models.py
class PurchaseOrder(models.Model):
def __str__(self):
return str(self.pk)
purchaseOrderId = models.CharField(max_length=30, null=True, blank=True, db_index=True)
issuedBy = models.ForeignKey('users.Company', null=True, blank=True, db_index=True, on_delete=models.CASCADE, related_name='issued_POs')
issuedAt = models.DateTimeField(null=True, blank=True, db_index=True)
issuedTo = models.ForeignKey('users.Company', null=True, blank=True, db_index=True, on_delete=models.CASCADE, related_name='received_POs')
referencePurchaseOrders = models.ManyToManyField('self', symmetrical=False, null=True, blank=True, db_index=True, related_name='related_POs')
internalManager = models.ForeignKey('users.CustomUser', null=True, blank=True, db_index=True, on_delete=models.CASCADE, related_name='managed_POs')
note = models.TextField(max_length=500, null=True, blank=True, db_index=True)
class ProductBatch(models.Model):
def __str__(self):
return str(self.pk)
purchaseOrder = models.ForeignKey('PurchaseOrder', null=True, blank=True, db_index=True, on_delete=models.CASCADE)
product = models.ForeignKey('products.Product', null=True, blank=True, db_index=True, on_delete=models.CASCADE)
quantity = models.IntegerField(null=True, blank=True, db_index=True)
unitprice = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True, db_index=True)
unitcurrency = models.ForeignKey('payments.Currency', null=True, blank=True, db_index=True, on_delete=models.CASCADE)
productSpendType = models.ForeignKey('ProductSpendType', on_delete=models.CASCADE, null=True, blank=True, db_index=True)
#views.py
def create_purchaseOrder(request):
submitted = False
ProductBatchFormset = formset_factory(ProductBatchForm, extra=1, can_order=True, can_delete=True)
if request.method == 'POST':
purchaseorder_form = PurchaseOrderForm(request.POST)
productbatch_formset = ProductBatchFormset(request.POST, prefix = 'pb')
if purchaseorder_form.is_valid() and productbatch_formset.is_valid():
po = purchaseorder_form.save()
for form in productbatch_formset:
pb = form.save()
return HttpResponseRedirect('/purchaseorder/create?submitted=True')
else:
return HttpResponseRedirect('/purchaseorder/create?'+str(purchaseorder_form.errors))
else:
context = {
'purchaseorder_form': PurchaseOrderForm(),
'productbatch_formset': ProductBatchFormset(prefix='pb')
}
return render(request, 'createpo.html', context)
#template
<form action="" method="post" id="myForm">
{% csrf_token %}
<div class="form-row" >
<div class="form-group col-md-3">
<label for="issuedBy" class="control-label">Issued by</label>
{{purchaseorder_form.issuedBy}}
</div>
<div class="form-group col-md-3">
<label for="issuedTo" class="control-label">Issued to</label>
{{purchaseorder_form.issuedTo}}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-2">
<label for="purchaseOrderId" class="control-label">PO number</label>
{{purchaseorder_form.purchaseOrderId}}
</div>
<div class="form-group col-md-2">
<label for="issuedAt" class="control-label">PO date</label>
{{purchaseorder_form.issuedAt}}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<label for="internalManager" class="control-label">Manager</label>
{{purchaseorder_form.internalManager}}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<label for="referencePurchaseOrders" class="control-label">Reference POs</label>
{{purchaseorder_form.referencePurchaseOrders}}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-4">
<label for="note" class="control-label">Notes</label>
{{purchaseorder_form.note}}
</div>
</div>
<br/>
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
{% for productbatch_form in productbatch_formset.forms %}
<tr>
<td>Product: {{productbatch_form.product}}</td>
<td>Quantity: {{productbatch_form.quantity}}</td>
<td>Currency: {{productbatch_form.unitcurrency}}</td>
<td>Unit Price: {{productbatch_form.unitprice}}</td>
<td>Spend Type: {{productbatch_form.productSpendType}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ productbatch_formset.management_form }}
<div>
<br/><br/>
<button class="btn btn-primary" type="submit">Create PO</button></div>
{% csrf_token %}
</form>
我希望表单和 formset 中的表单一样保存,但只有 formset 中的表单在保存。非常感谢您的帮助!
【问题讨论】:
-
能否包含完整的错误回溯?
-
添加了回溯。谢谢!
标签: django django-forms modelform