我觉得我必须遗漏一些明显的东西,但我遇到的问题是我的模型表格集在提交后仍坚持保留他们的数据。我正在创建一个页面,允许用户创建项目,然后向该项目添加任意数量的材料。 JavaScript负责根据需要动态添加formset的新实例。代码在第一次运行正常,之后它“记住”以前的数据。它适用于材质formset,但不适用于它上面的常规模型。
我认为它必须与我创建模型formset的方式有关。当请求页面时,视图似乎传回绑定到旧数据而不是未绑定集的formset。我是Django的新手,我正在努力教自己,所以有可能工作的东西我还没有完全掌握。以下是视图的代码:
def addproject_page(request):
# Define the formset to use to add the materials
MaterialFormSet = modelformset_factory(Material, exclude = ('project',))
# Check to see if there is some POST data from an attempt to fill out the form
if request.method == 'POST':
# Create a form for the project and for the material and use a prefix to separate the POST data for the two
project_form = ProjectForm(request.POST, prefix='project')
# Instantiate the formset to display multiple materials when creating a project
material_formset = MaterialFormSet(request.POST, prefix='material')
# Check both forms with the validators and if both are good process the data
if project_form.is_valid() and material_formset.is_valid():
# Save the data for the newly created project
created_project = project_form.save()
# Tell each material to be associated with the above created project
instances = material_formset.save(commit=False)
for instance in instances:
instance.project = created_project
instance.save()
# After the new project and its materials are created, go back to the main project page
return HttpResponseRedirect('/members/projects/')
# If there is no post data, create and show the blank forms
else:
project_form = ProjectForm(prefix='project')
material_formset = MaterialFormSet(prefix='material')
return render(request, 'goaltracker/addproject.html', {
'project_form': project_form,
'material_formset': material_formset,
})
编辑以添加我的模板代码,以防它有用:
{% extends "base.html" %}
{% block external %}
<script src="{{ static_path }}js/projects.js" type="text/javascript"></script>
{% endblock %}
{% block title %}: Add Project{% endblock %}
{% block content %}
<h1>Add a Project</h1>
<form id="new_project_form" method="post" action="">
{{ project_form.as_p }}
<!-- The management form must be rendered first when iterating manually -->
<div>{{ material_formset.management_form }}</div>
<!-- Show the initial blank form(s) before offering the option to add more via JavaScript -->
{% for material_form in material_formset.forms %}
<div>{{ material_form.as_p }}</div>
{% endfor %}
<input type="button" value="Add Material" id="add_material">
<input type="button" value="Remove Material" id="remove_material">
<input type="submit" value="add" />
</form>
{% endblock %}
答案 0 :(得分:3)
我认为您需要use a custom queryset,以便使用空查询集实例化您的formset。您需要在POST
语句的GET
和if
分支中指定查询集。
if request.method == "POST":
...
material_formset = MaterialFormSet(request.POST, prefix='material', queryset=Material.objects.none())
...
else:
material_formset = MaterialFormSet(prefix='material', queryset=Material.objects.none())
目前,您的formset正在使用默认查询集,其中包含模型中的所有对象。
答案 1 :(得分:0)
问题the old data is always persists in modelformset
的答案就在这里。文档中给出的https://docs.djangoproject.com/en/1.8/topics/forms/modelforms/#changing-the-queryset通过覆盖basemodelformset的构造函数来改变查询集
from django.forms.models import BaseModelFormSet
from myapp.models import Author
class CalendarFormset(BaseModelFormSet):
def __init__(self, *args, **kwargs):
super(CalendarFormset, self).__init__(*args, **kwargs)
self.queryset = Calendar.objects.none()