You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改Django ModelFormSet标签:将Vote替换为对应字幕名称

解决ModelFormSet投票字段标签替换为字幕名称的问题

实现思路

每个投票表单对应一个特定字幕,核心是在视图层初始化FormSet时,为每个表单的vote字段动态设置标签为对应字幕名称,同时确保提交后能正确关联到对应字幕记录。


具体步骤

1. 修改视图层代码

先获取当前投票对应的字幕列表(可从选举关联数据读取,或手动定义),初始化FormSet时为每个表单设置字段标签,并处理表单提交逻辑:

from django.shortcuts import render
from .models import YesNoVote, YesNoElection
from .forms import YesNoVotingForm
from django.forms import modelformset_factory

def voting_view(request, election_id):
    # 获取当前选举实例(替换为你的实际获取逻辑)
    election = YesNoElection.objects.get(id=election_id)
    # 替换为你的实际字幕来源,比如从选举关联的字幕数据中读取
    subtitles = ["字幕A", "字幕B", "字幕C"]
    
    # 动态设置FormSet的extra数量为字幕总数
    VoteFormSet = modelformset_factory(YesNoVote, form=YesNoVotingForm, extra=len(subtitles))

    if request.method == 'POST':
        formset = VoteFormSet(request.POST)
        if formset.is_valid():
            # 批量保存投票记录,关联用户、选举和对应字幕
            instances = formset.save(commit=False)
            for idx, instance in enumerate(instances):
                instance.user = request.user
                instance.election = election
                instance.subtitle = subtitles[idx]
                instance.save()
            return render(request, 'voting_success.html')
    else:
        # 初始化空表单集(针对新投票场景)
        formset = VoteFormSet(queryset=YesNoVote.objects.none())
        # 为每个表单的vote字段设置字幕名称作为标签
        for idx, form in enumerate(formset):
            form.fields['vote'].label = subtitles[idx]

    return render(request, 'voting.html', {'formset': formset})

2. 可选:调整表单类(添加隐藏字段传递字幕)

如果需要通过表单隐藏字段传递字幕值(替代视图层通过索引匹配的方式),修改YesNoVotingForm:

from django import forms
from .models import YesNoVote

class YesNoVotingForm(forms.ModelForm):
    class Meta: 
        model = YesNoVote
        fields = ['vote', 'subtitle']
        widgets = {
            'vote': forms.Select(attrs={"required": True}),
            'subtitle': forms.HiddenInput()  # 隐藏字段存储字幕名称
        }

此时视图初始化FormSet时,还需为隐藏字段设置初始值:

# 在else分支的循环中添加
form.fields['subtitle'].initial = subtitles[idx]

3. 可选:优化模板渲染

若想更精准控制表单显示,可手动渲染字段标签和控件,避免默认渲染的冗余内容:

<form method="post">
    {{ formset.management_data }}
    {% csrf_token %}
    {% for form in formset %}
        <!-- 渲染所有隐藏字段 -->
        {% for field in form.hidden_fields %}
            {{ field }}
        {% endfor %}
        <!-- 自定义渲染投票字段 -->
        <label>{{ form.vote.label }}</label>
        {{ form.vote }}
        <br>
    {% endfor %}
    <button type="submit" name="voting" class="btn btn-primary save">Submit</button>
    Let op: Je kunt je stem niet meer wijzigen.
</form>

关键注意事项

  • 确保字幕列表长度与FormSet的extra值一致,避免表单数量不匹配
  • 若处理用户修改已有投票的场景,需用对应投票实例的queryset初始化FormSet,此时可从实例中读取字幕设置标签:form.fields['vote'].label = form.instance.subtitle

内容的提问来源于stack exchange,提问作者Annelotte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 10:57:08