出于某种原因,我对django-dynamic-formset的实现表现得有点滑稽。
它为我的模板中的每个动态formset创建了两个添加/删除链接。
我一直在试图弄清楚这一点,并且它得到了我的最好。
here是我正在谈论的错误的屏幕截图
如果您想自己触发错误,我也可以提供登录信息 这是我的模板:
<head>
<script type="text/javascript" src="{{ STATIC_URL }}jquery.formset.js"></script>
<script type="text/javascript">
$(function() {
$('#ingredients tbody tr').formset({
prefix: '{{ ingredients_formset.prefix }}',
formCssClass: 'dynamic-ingredients'
});
$('#steps tbody tr').formset({
prefix: '{{ steps_formset.prefix }}',
formCssClass: 'dynamic-steps'
});
})
</script>
</head>
<body>
<form action="{% url cookbook.views.createrecipe %}" method="POST" id="ingredients">
{% csrf_token %}
<table>
<tbody>
<tr>
<label>
Ingredients:
</label>
</tr>
<tr>
<td>
<input type="text" cols="40" rows="10" />
</td>
</tr>
</tbody>
</table>
</form>
<form action="{% url cookbook.views.createrecipe %}" method="POST" id="steps">
{% csrf_token %}
<table>
<tbody>
<label>
Steps:
</label>
<tr>
<td>
<input type="text" cols="40" rows="10" />
</td>
</tr>
</tbody>
</table>
</form>
</body>
这里是forms.py
class RecipeForm(forms.ModelForm):
reset_recipe = forms.CharField(widget=forms.HiddenInput(), required = False)
class Meta:
model = Recipe
widgets = {'original_cookbook':forms.HiddenInput(),
'pub_date':forms.HiddenInput(),
'author':forms.HiddenInput()}
fields =("name", "picture","ingredients","steps","prep_time","type",'reset_recipe')
class CookbookForm(forms.ModelForm):
class Meta:
model = Cookbook
class StepsForm(forms.Form):
Step = forms.CharField()
StepsFormSet = formset_factory(RecipeForm, StepsForm, can_order=True, can_delete=True, extra = 0)
class IngredientsForm(forms.Form):
Ingredient = forms.CharField()
IngredientsFormSet = formset_factory(RecipeForm, IngredientsForm, can_order=True, can_delete=True, extra = 0)
和视图:
def createrecipe(request):
RecipeForm = RecipeForm(request.POST)
IngredientsFormSet = formset_factory(IngredientsForm)
StepsFormSet = formset_factory(StepsForm)
if request.method == 'POST':
form = RecipeForm(request.POST)
ingredients_formset = IngredientsFormSet(request.POST, request.FILES, prefix='ifs')
steps_formset = StepsFormSet(request.POST, request.FILES, prefix='sfs')
if form.is_valid() and ingredients_formset.is_valid() and steps_formset.is_valid():
print "form is valid"
new_recipe = form.save(commit=False)
new_recipe.original_cookbook = request.user.cookbooks.all()[0]
new_recipe.author = request.user.cookbooks.all()[0].name
new_recipe.steps = steps_formset
new_recipe.ingredients = ingredients_formset
new_recipe.save()
cookbooks = request.user.cookbooks.all()
cookbook = cookbooks[0]
cookbook.recipes.add(new_recipe)
form.save_m2m()
t = loader.get_template('cookbook/create_form.html')
c = RequestContext(request, {
'form': new_recipe,
})
data = {
'replace': True,
'form': t.render(c),
'success': True,
}
json = simplejson.dumps(data)
return HttpResponse(json, mimetype='text/plain')
else:
print "form is invalid"
form = RecipeForm(request.POST)
ingredients_formset = IngredientsFormSet(request.POST, request.FILES, prefix='ifs')
steps_formset = StepsFormSet(request.POST, request.FILES, prefix='sfs')
t = loader.get_template('cookbook/create_form.html')
c = RequestContext(request, {
'form':form,
})
data ={
'form': t.render(c),
'success': False,
}
json = simplejson.dumps(data)
return HttpResponse(json, mimetype='text/plain')
答案 0 :(得分:0)
我现在正在项目中使用它,让我告诉你我现在是怎么做的,让我们来看看标记:
<div id="id_p_i_c_formset_div">
{% for form in p_i_c_formset.forms %}
<div class="p_i_c_child_formset row-fluid">
{{ form.id }}
<h2>year</h2>
{{ form.year }}
<h2>product_category</h2>
{{ form.product_category }}
<h2>insurance_company</h2>
{{ form.insurance_company }}
<h2>value</h2>
{{ form.value|attr:"placeholder:insurance_claims" }}
<h2>result</h2>
{{ form.result }}
</div>
{% endfor %}
{{ p_i_c_formset.management_form }}
</div>
然后,在javascript中你需要做正确的选择器(你的formset的字段所在的位置),这是插件将获取代码以使用适当的id和名称克隆它的地方,不要忘记pase它是formset的“前缀”:
$(function(){
$('form#my-personal-info #id_p_i_c_formset_div .p_i_c_child_formset').formset({
prefix: '{{ p_i_c_formset.prefix }}'
});
});
插件会自动创建删除和添加按钮。