Django:更新/编辑填充的表单和表单集

时间:2018-07-04 08:12:25

标签: django forms view formset

有人可以帮助我回答为什么我的更新视图功能无法运行吗?它返回填充的表单和表单集,没有错误消息(也没有文件附件)。

这是在使用表单集(由modelformset_factory制作)更新函数后发生的:

def recipe_update(request, id=None):
if request.method == 'GET':
    instance = get_object_or_404(Recipe, id=id, user=request.user)
    form = RecipeForm(request.POST or None, request.FILES or None, instance=instance)
    formset = IngredientModelFormset(queryset=Ingredient.objects.filter(recipe=instance))
elif request.method == 'POST':
    instance = get_object_or_404(Recipe, id=id, user=request.user)
    form = RecipeForm(request.POST, request.FILES or None)
    formset = IngredientModelFormset(request.POST, request.FILES or None)
    if form.is_valid() and formset.is_valid():
        recipe = form.save()
        for forms in formset:
            ingredient = forms.save(commit=False)
            ingredient.recipe = recipe
            ingredient.save()
        return redirect(recipe.get_absolute_url())
context = {
    "instance": instance,
    "form": form,
    'formset': formset,
}
return render(request, "recipes/recipe_form.html", context)

创建功能正常运行:

def recipe_create(request):
if request.method == 'GET':
    form = RecipeForm(request.POST or None, request.FILES or None)
    formset = IngredientModelFormset(queryset=Ingredient.objects.none())
elif request.method == 'POST':
    form = RecipeForm(request.POST, request.FILES or None)
    formset = IngredientModelFormset(request.POST, request.FILES or None)
    if form.is_valid() and formset.is_valid():
        recipe = form.save()
        for forms in formset:
            ingredient = forms.save(commit=False)
            ingredient.recipe = recipe
            ingredient.save()
        return redirect(recipe.get_absolute_url())
context = {
    "form": form,
    'formset': formset,
}
return render(request, "recipes/recipe_form.html", context)

非常感谢!

更新

我根据建议更改了代码,现在出现以下错误:['ManagementForm数据丢失或已被篡改']

我正在模板中使用management_form:

{{ formset.management_form }}
{% for forms in formset %}
<div class="row form-row spacer">
    <div class="col-2">
        <label>{{ forms.name.label }}</label>
    </div>
    <div class="col-4">
        <div class="input-group">
            {{ forms.name }}
            <div class="input-group-append">
                <button class="btn btn-success add-form-row">+</button>
            </div>
        </div>
    </div>
</div>
{% endfor %}

这是更新的视图代码:

def recipe_update(request, id=None):
  instance = get_object_or_404(Recipe, id=id, user=request.user)
  form = RecipeForm(request.POST, request.FILES or None, instance=instance)
  formset = IngredientModelFormset(request.POST, request.FILES or None, instance=instance)
  if form.is_valid() and formset.is_valid():
    recipe = form.save()
    recipe.user = request.user
    recipe.save()
    for forms in formset:
        ingredient = forms.save(commit=False)
        ingredient.recipe = recipe
        ingredient.save()
    return redirect(recipe.get_absolute_url())
  context = {
    "instance": instance,
    "form": form,
    'formset': formset,
  }
  return render(request, "recipes/recipe_form.html", context)

1 个答案:

答案 0 :(得分:0)

您需要使用inline formset。在更新视图内部,您还需要为实例请求传递实例参数:

def recipe_update(request, id=None):
    if request.method == 'GET':
        instance = get_object_or_404(Recipe, id=id, user=request.user)   
        form = RecipeForm(request.POST or None, request.FILES or None, instance=instance)
        formset = IngredientModelFormset(queryset=Ingredient.objects.none(), instance=instance)
    elif request.method == 'POST':
        instance = get_object_or_404(Recipe, id=id, user=request.user)
        form = RecipeForm(request.POST, request.FILES or None, instance=instance)
        formset = IngredientModelFormset(request.POST, request.FILES or None, instance=instance)

此外,您无需使用request.POST or None快捷方式检查请求类型。您可以简单地将代码重写为此:

def recipe_update(request, id=None):
    instance = get_object_or_404(Recipe, id=id, user=request.user)  
    form = RecipeForm(request.POST or None, request.FILES or None, instance=instance)
    formset = IngredientModelFormset(request.POST or None, request.FILES or None, instance=instance)
    if form.is_valid() and formset.is_valid():
    # rest of your code