为什么第一个ModelFormSet不能从request.POST中获取ID?

时间:2019-07-21 19:20:53

标签: python django django-forms

我正在尝试使用ModelFormSetFactory添加多个ModelForm。提交后,第一个集合将返回错误消息“((隐藏的字段ID)此字段是必需的。”即使隐藏的ID字段为表格形式。对于此集中的任何其他表格,都不会发生此错误,并且可以在cleaned_data中找到该ID。

此表单的视图(在views.py中):

class NewRecipeView(generic.TemplateView):
    def get(self, request, *args, **kwargs):
        ingredient_data = {
                'ingredient-TOTAL_FORMS': '0',
                'ingredient-INITIAL_FORMS': '1',
        }
        context = {"new_page": "active",
                   "form": RecipeForm(),
                   "formset_ingredient": RecIngFormSet(ingredient_data, prefix="ingredient"),
        }
        return render(request, 'recipes/new_recipe.html', context)

    def post(self, request):
        form = RecipeForm(request.POST)
        formset_ingredient = RecIngFormSet(request.POST, prefix="ingredient")
        print(request.POST)
        for fs in formset_ingredient:
            print(fs)
            print(fs.cleaned_data)
        if form.is_valid() and formset_ingredient.is_valid():
            new_rec = form.save(commit=False)
            new_rec.created_at = timezone.now()
            new_rec.save()
            for fs in formset_ingredient:
                new_rec_ing = fs.save(commit=False)
                new_rec_ing.recipe = new_rec
                new_rec_ing.save()
            return HttpResponseRedirect(reverse('recipes:recipe', args=(new_rec.id,)))
        else:
            print('handle invalid forms here')

以及form.py中的实际表格:

class RecipeIngredientForm(forms.ModelForm):
    class Meta:
        model = RecipeIngredient
        fields = ['quantity', 'unit', 'ingredient']


recIngFormSet = modelformset_factory(RecipeIngredient, RecipeIngredientForm)

在HTML中,我使用JavaScript从{{ formset_ingredient.empty_form }}构建表单,并确保遵循{{ formset_ingredient.management_form }}中设置的规则。我认为这很不错,因为POST看起来不错(对我来说),我认为这只是对POST的处理。

request.POST的示例是:

<QueryDict: {'csrfmiddlewaretoken': ['rMETmq9lkOnN5Nmath3pOa2m2YjMWYWTqcNY7MIcdrbUDUkLxKwcNqZHIrE9iWj2'], 'name': ['Rec Name'], 'serves': ['1'], 'ingredient-TOTAL_FORMS': ['2'], 'ingredient-INITIAL_FORMS': ['1'], 'ingredient-MIN_NUM_FORMS': [''], 'ingredient-MAX_NUM_FORMS': [''], 'ingredient-0-quantity': ['1'], 'ingredient-0-unit': ['lb'], 'ingredient-0-ingredient': ['1'], 'ingredient-0-id': [''], 'ingredient-1-quantity': ['2'], 'ingredient-1-unit': ['lb'], 'ingredient-1-ingredient': ['2'], 'ingredient-1-id': [''], 'ingredient-__prefix__-quantity': [''], 'ingredient-__prefix__-unit': [''], 'ingredient-__prefix__-ingredient': [''], 'ingredient-__prefix__-id': ['']}>

然后Django将前缀格式集“ ingredient”转换为{'quantity': Decimal('1'), 'unit': '1', 'ingredient': <Ingredient: orange>}{'quantity': Decimal('2'), 'unit': 'lb', 'ingredient': <Ingredient: banana>, 'id': None} 问题是我认为第一个也应该有'id': None

感谢您能提供的任何帮助。如果您需要更多信息或代码段,请告诉我。

1 个答案:

答案 0 :(得分:0)

我已经对FormSets和FormSetFactories进行了更多的阅读,问题是我没有足够全面地阅读文档。

以下行默认创建一个表单集,其中包含一个表单:

RecNoteFormSet = modelformset_factory(RecipeNote, RecipeNoteForm)

因此,无需像我在此处那样定义管理表单配置:

        ingredient_data = {
                'ingredient-TOTAL_FORMS': '0',
                'ingredient-INITIAL_FORMS': '1',
        }

我仍然不确定100%为什么我的请求没有被正确读取,但是现在我使用了更多的Django功能,并且越来越少地依靠javascript在前端上构建表单,因此此问题得以解决。 / p>