在 Django 表单中传递自定义表单值到视图

在Django中,我们可以通过表单的初始化参数initial来传递自定义的初始值给表单字段。如果我们想要在视图中设置表单的初始值,可以在视图中创建表单的实例时,传递一个字典给initial参数。

1、问题背景

我们遇到了这样一个问题:在使用 Django 表单时,我们希望将自定义表单中的值传递到视图中。然而,我们发现无法为多选选项的每个选项传递值。在渲染表单时,只有一个字符字段,而多选框中有多个选择。我们想知道是否有办法解决这个问题,以及表单集是否可以在这里提供帮助。我们对 Django 还很陌生,因此希望得到一些解释,以便更好地理解和学习。

python 复制代码
# models.py
class StateOption(models.Model):
    partstate = models.ForeignKey(State)
    partoption = models.ForeignKey(Option)
    relevantoutcome = models.ManyToManyField(Outcome, through='StateOptionOutcome')

class StateOptionOutcome(models.Model):
    stateoption = models.ForeignKey(StateOption)
    relevantoutcome = models.ForeignKey(Outcome)
    outcomevalue = models.CharField(max_length=20)

# forms.py
class UpdateStateOptionWithOutcomesForm(forms.ModelForm):
    class Meta:
        model = StateOption
        exclude = ['partstate', 'partoption']

    def __init__(self, *args, **kwargs):
        super(UpdateStateOptionWithOutcomesForm, self).__init__(*args, **kwargs)
        self.fields['relevantoutcome'] = forms.ModelMultipleChoiceField(queryset=Outcome.objects.all(), required=True, widget=forms.CheckboxSelectMultiple)
        self.fields['outcomevalue'] = forms.CharField(widget=forms.TextInput(attrs={'size': '30'}))

# views.py
stateoption = get_object_or_404(StateOption, pk=stateoption_id)

if request.method == "POST":
    form = UpdateStateOptionWithOutcomesForm(request.POST, instance=stateoption)
    if form.is_valid():
        cd = form.cleaned_data
        outcomevalue = cd['outcomevalue']

        for outcome_id in request.POST.getlist('relevantoutcome'):
            stateoption_outcome = StateOptionOutcome.objects.create(stateoption=stateoption, relevantoutcome_id=int(outcome_id), outcomevalue=outcomevalue) 

# template.html
{% for field in form %}
    {{ field.label }}:
    {{ field }}
    {% if field.errors %}
        {{ field.errors|striptags }}
    {% endif %}
{% endfor %}

2、解决方案

方法一:生成所需数量的字段

一种解决方案是编写一个循环来生成所需数量的字段。例如:

python 复制代码
# forms.py
# ...

outcome_qs = Outcome.objects.all()
self.fields['relevantoutcome'] = forms.ModelMultipleChoiceField(queryset=outcome_qs, required=True, widget=forms.CheckboxSelectMultiple)
for outcome in outcome_qs:
    # Use Outcome primary key to easily match two fields in your view.
    self.fields['outcomevalue_%s' % outcome.pk] = forms.CharField(widget=forms.TextInput(attrs={'size':'30'}) 

方法二:使用表单集

另一种解决方案是使用表单集。表单集允许我们创建一组类似的表单,每个表单都可以处理单个对象。在我们的例子中,我们可以创建一个表单集来处理每个 StateOptionOutcome 对象。

python 复制代码
# forms.py
class StateOptionOutcomeForm(forms.ModelForm):
    class Meta:
        model = StateOptionOutcome
        fields = ['relevantoutcome', 'outcomevalue']

StateOptionOutcomeFormSet = forms.formset_factory(StateOptionOutcomeForm, extra=1)

# views.py
stateoption = get_object_or_404(StateOption, pk=stateoption_id)

if request.method == "POST":
    formset = StateOptionOutcomeFormSet(request.POST)
    if formset.is_valid():
        for form in formset:
            stateoption_outcome = StateOptionOutcome.objects.create(stateoption=stateoption, **form.cleaned_data)

使用表单集的好处是,我们可以轻松地处理多个对象,而且代码也更加简洁。

相关推荐
一只鹿鹿鹿4 小时前
政务外网整体设计方案(PPT)
大数据·数据库·web安全·系统安全·流程图·政务
2603_965148115 小时前
社区与学习资源:从入门到精通的API选品学习路径
数据库·人工智能·python·学习·数据挖掘
AI砖家5 小时前
安全进入 Agent Loop:2027 年 Coding Agent 的决胜点
数据库·安全·codex·vibecoding
wangqiaowq5 小时前
SQL server C盘空间占满的处理
数据库·sql
文人sec5 小时前
SQL基础入门笔记 | 从零基础到掌握核心查询语句
数据库·笔记·sql
数字新视界5 小时前
机房动环监控提升运维效率
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
SelectDB技术团队6 小时前
冷热分层从建到验:Storage Policy 创建、表级与分区级绑定、SHOW TABLETS 验证的完整命令
大数据·数据库·elasticsearch·搜索引擎·数据分析·apache doris·冷热分层
lambo mercy7 小时前
Day3:结构化输出
java·数据库·oracle
派小心.8 小时前
小程序分享链路中来源参数的传递校验
大数据·前端·数据库·人工智能·小程序·数据分析
Είναι η κοπέλα8 小时前
向量数据库与嵌入模型:Chroma/FAISS/Milvus 选型
数据库·milvus·faiss