首页 > 解决方案 > Django:更新/编辑填充表单和表单集

问题描述

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

这发生在使用 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 data is missing or has been tampered with']

我在模板中使用 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)

标签: djangoformsviewformset

解决方案


您需要使用内联 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 

推荐阅读