【问题标题】:Django: Update/edit populated form and formsetDjango:更新/编辑填充表单和表单集
【发布时间】:2018-12-12 14:38:12
【问题描述】:

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

这发生在使用 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)

create 函数工作正常:

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)

【问题讨论】:

    标签: django forms view formset


    【解决方案1】:

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

    【讨论】:

    • 非常感谢 - 现在它实际上正在保存对象。但它没有预先填充表单集(仅表单)。知道这是为什么吗?
    • @Jaacob 看起来我错过了request.POST 部分:formset = IngredientModelFormset(request.POST or None, request.FILES or None, instance=instance)。你现在还使用 inlineformset_factory 吗?
    • 是的,我改为 inlineformset_factory。当我使用它时它似乎会保存但不会填充:formset = IngredientModelFormset(queryset=Ingredient.objects.none(), instance=instance) 当我使用它时它会填充但不会保存:IngredientModelFormset(request.POST or None, request.FILES 或 None,instance=instance)
    • @Jaacob 这很奇怪。您可以在问题中添加更新的代码吗?
    • 我现在已经更新了这个问题 - 我现在这个问题有点新,但如果你有任何建议会很棒。非常感谢!
    猜你喜欢
    • 2018-09-06
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 2011-04-11
    • 1970-01-01
    • 2016-06-23
    • 2020-07-25
    • 2018-01-29
    相关资源
    最近更新 更多