如何保存 Django ModelFormSet?
How to save Django ModelFormSet?
我现在很绝望,我想不通。对我来说这应该很容易做到,但我还没有找到任何解释这一点的答案。
两个模型之间没有外键:
class Employee(models.Model):
surname = models.CharField(max_length=100)
name = models.CharField(max_length=100)
class Salary(models.Model):
date = models.DateField(auto_now_add=True)
surname = models.CharField(max_length=100)
name = models.CharField(max_length=100)
salary = models.DecimalField(max_digits=20, decimal_places=2)
要保存到模型 B 的一个模型表单集。
SalaryFormSet = modelformset_factory(Salary, extra=0)
然后在views.py:
def createForm(request):
formset = SalaryFormSet(queryset=Employee.objects.all())
return render(request, 'formfile.html', {'formset': formset})
def submitForm(request)
f = ModelBFormSet(request.POST)
if f.is_valid():
f.save()
return HttpResponse('Submitted successfully')
else:
return HttpResponse(f.errors, request.POST)
在formfile.html中:
<form action="submitForm/" method="post">
{{ formset.management_form }}
<table>
{{ formset }}
</table>
{% csrf_token %}
<input type="submit" value="Submit">
</form>
我一点击提交,表单集就被解析为无效并且 f.errors 状态(对于 Employee 中的每一行):
<ul class="errorlist"><li>id<ul class="errorlist"><li>Select a valid choice. That choice is not one of the available choices.</li></ul></li></ul>
我只想将 Employee 中所有行的姓和名预加载到 SalaryFormSet 中,我应该为每一行输入薪水并将它们保存到 Salary。不应更新 Salary 中的记录,但应创建一个新条目。
Employee 模型已经有从管理站点创建的记录。随着员工工资的增加,我会从工资模型生成工资单,并从最新日期获取相关工资。
如果我将查询集更改为 queryset=Salary.objects.none() 并将 SalaryFormSet 更改为 extra=2,则模板呈现为空。如果我手动插入姓氏、姓名和薪水,表单集会正确保存。工资中的两个新条目。为什么我不能只预加载名称(我应该将它们加载为 str() 吗?)并手动添加薪水?
正如我在评论中所说,将 Employees 的查询集传递给 Salary 表单集的实例化是没有意义的。我认为鉴于您出于某种原因试图将这两个模型完全分开,并且您希望每次都创建新的 Salary 实例,您最好只传递一组 initial
数据。
这里有点tricky,因为initial只适用于extra forms,extra是formset factory设置的,所以需要在视图中进行。像这样:
employees = Employee.objects.values('name', 'surname')
SalaryFormSet = modelformset_factory(Salary, extra=len(employees))
formset = SalaryFormSet(initial=employees, queryset=Salary.objects.none())
这只是根据 Daniel Roseman 的解决方案总结答案。
在models.py中:
class Employee(models.Model):
surname = models.CharField(max_length=100)
name = models.CharField(max_length=100)
class Salary(models.Model):
date = models.DateField(auto_now_add=True)
surname = models.CharField(max_length=100)
name = models.CharField(max_length=100)
salary = models.DecimalField(max_digits=20, decimal_places=2)
在forms.py中:
employees = Employee.objects.values('surname', 'name')
SalaryFormSet = modelformset_factory(Salary, extra=len(employees)
在views.py中:
def createForm(request):
formset = SalaryFormSet(initial=employees, queryset=Salary.objects.none())
return render(request, 'formfile.html', {'formset': formset})
def submitForm(request)
f = ModelBFormSet(request.POST)
if f.is_valid():
f.save()
return HttpResponse('Submitted successfully')
else:
return HttpResponse(f.errors, request.POST)
我现在很绝望,我想不通。对我来说这应该很容易做到,但我还没有找到任何解释这一点的答案。
两个模型之间没有外键:
class Employee(models.Model):
surname = models.CharField(max_length=100)
name = models.CharField(max_length=100)
class Salary(models.Model):
date = models.DateField(auto_now_add=True)
surname = models.CharField(max_length=100)
name = models.CharField(max_length=100)
salary = models.DecimalField(max_digits=20, decimal_places=2)
要保存到模型 B 的一个模型表单集。
SalaryFormSet = modelformset_factory(Salary, extra=0)
然后在views.py:
def createForm(request):
formset = SalaryFormSet(queryset=Employee.objects.all())
return render(request, 'formfile.html', {'formset': formset})
def submitForm(request)
f = ModelBFormSet(request.POST)
if f.is_valid():
f.save()
return HttpResponse('Submitted successfully')
else:
return HttpResponse(f.errors, request.POST)
在formfile.html中:
<form action="submitForm/" method="post">
{{ formset.management_form }}
<table>
{{ formset }}
</table>
{% csrf_token %}
<input type="submit" value="Submit">
</form>
我一点击提交,表单集就被解析为无效并且 f.errors 状态(对于 Employee 中的每一行):
<ul class="errorlist"><li>id<ul class="errorlist"><li>Select a valid choice. That choice is not one of the available choices.</li></ul></li></ul>
我只想将 Employee 中所有行的姓和名预加载到 SalaryFormSet 中,我应该为每一行输入薪水并将它们保存到 Salary。不应更新 Salary 中的记录,但应创建一个新条目。
Employee 模型已经有从管理站点创建的记录。随着员工工资的增加,我会从工资模型生成工资单,并从最新日期获取相关工资。
如果我将查询集更改为 queryset=Salary.objects.none() 并将 SalaryFormSet 更改为 extra=2,则模板呈现为空。如果我手动插入姓氏、姓名和薪水,表单集会正确保存。工资中的两个新条目。为什么我不能只预加载名称(我应该将它们加载为 str() 吗?)并手动添加薪水?
正如我在评论中所说,将 Employees 的查询集传递给 Salary 表单集的实例化是没有意义的。我认为鉴于您出于某种原因试图将这两个模型完全分开,并且您希望每次都创建新的 Salary 实例,您最好只传递一组 initial
数据。
这里有点tricky,因为initial只适用于extra forms,extra是formset factory设置的,所以需要在视图中进行。像这样:
employees = Employee.objects.values('name', 'surname')
SalaryFormSet = modelformset_factory(Salary, extra=len(employees))
formset = SalaryFormSet(initial=employees, queryset=Salary.objects.none())
这只是根据 Daniel Roseman 的解决方案总结答案。
在models.py中:
class Employee(models.Model):
surname = models.CharField(max_length=100)
name = models.CharField(max_length=100)
class Salary(models.Model):
date = models.DateField(auto_now_add=True)
surname = models.CharField(max_length=100)
name = models.CharField(max_length=100)
salary = models.DecimalField(max_digits=20, decimal_places=2)
在forms.py中:
employees = Employee.objects.values('surname', 'name')
SalaryFormSet = modelformset_factory(Salary, extra=len(employees)
在views.py中:
def createForm(request):
formset = SalaryFormSet(initial=employees, queryset=Salary.objects.none())
return render(request, 'formfile.html', {'formset': formset})
def submitForm(request)
f = ModelBFormSet(request.POST)
if f.is_valid():
f.save()
return HttpResponse('Submitted successfully')
else:
return HttpResponse(f.errors, request.POST)