Django表单中如何配置Survey与Question一对多动态字段
模型层先修正外键关系
你当前的模型外键配置颠倒了一对多的从属关系:如果一份问卷(Survey)可对应多个问题(Question),外键字段应该定义在「多」的一侧也就是Question模型中,而非Survey侧。
修正后的models.py代码:
# models.py from django.db import models class Survey(models.Model): survey_name = models.CharField(max_length=200) def __str__(self): return self.survey_name class Question(models.Model): # 外键关联问卷,一个问卷对应多个问题 survey = models.ForeignKey(Survey, on_delete=models.CASCADE, related_name="questions") question_text = models.CharField(max_length=200) def __str__(self): return self.question_text
其中related_name="questions"配置可保留你原有的调用习惯,后续直接通过问卷实例.questions就能获取该问卷关联的所有问题。
表单层用Formset实现动态多问题提交
直接用Django自带的ModelForm + 内联表单集即可实现单页同时提交问卷名称和任意数量的问题,forms.py代码如下:
# forms.py from django import forms from django.forms import inlineformset_factory from .models import Survey, Question # 问卷主表单 class SurveyForm(forms.ModelForm): class Meta: model = Survey fields = ['survey_name'] # 问题内联表单集:绑定到Survey模型的关联Question,提交时可同时处理多个问题表单 QuestionFormSet = inlineformset_factory( Survey, Question, fields=['question_text'], # 初始展示3个空问题输入框,可根据需求调整 extra=3, # 允许用户删除新增的问题 can_delete=True )
配套使用说明
- 视图层处理逻辑:先校验
SurveyForm,保存生成Survey实例后,再将Survey实例传入QuestionFormSet,校验通过后批量保存问题即可 - 前端动态添加问题:可通过JS复制现有问题表单的DOM结构,修改对应表单字段的索引值即可实现新增,注意必须渲染
{{ formset.management_form }}字段,否则Django无法识别动态新增的表单 - 提交时所有表单字段放在同一个form标签内提交即可,无需分开请求
内容的提问来源于stack exchange,提问作者walter_dane
相关产品推荐
相关产品推荐

