2011-11-01 79 views
3

我觉得我必须错过一些明显的东西,但我有一个问题,我的模型框架坚持在提交后保留他们的数据。我正在创建一个页面,允许用户创建一个项目,然后为该项目添加任意数量的材料。 JavaScript正在照顾根据需要动态添加formset的新实例。该代码第一次正常工作,之后它“记住”以前的数据。它发生在材质formset上,而不是它上面的常规模型。Django模型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

讨论了同样的问题,该代码看起来不错。当你看到这个问题时你在做什么?你如何重新显示页面 - 它可能只是你的浏览器缓存数据? –

+0

我在想它可能是浏览器缓存。我清除了缓存,并且尝试从完全不同的浏览器访问该页面,但数据甚至在其他浏览器中出现。它甚至在停止并启动开发服务器后仍然存在。我可以通过删除会话和相关表并重新运行syncdb来实现“重置” –

回答

3

我想你需要use a custom queryset,让你的表单集与实例化空的查询集。您需要在if语句的POSTGET分支中指定查询集。

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正在使用默认queryset,其中包含模型中的所有对象。

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() 

的构造chenge的查询集在这里
django modelformset_factory sustains the previously submitted data even after successfully created the objects