2011-11-01 85 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