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

如何在Django模板中向modelform_factory传递行ID参数

解决方法

方法一:在表单类中添加隐藏字段(推荐)

这种方法更规范,能利用Django表单的验证机制,避免手动处理字段命名的问题。

  1. 定义表单类
    在forms.py里给你的发放表单添加一个隐藏字段,用来存储对应产品的ID:
from django import forms
from .models import Issuance

class IssuanceForm(forms.ModelForm):
    # 隐藏字段,用于传递产品ID
    product_id = forms.IntegerField(widget=forms.HiddenInput())

    class Meta:
        model = Issuance
        fields = ['checked', 'factory']  # 替换成你实际需要的字段
  1. 视图中初始化Formset并绑定产品ID
    在视图里根据products_info的数量生成Formset,同时给每个表单的product_id赋值对应产品的ID:
from django.forms import formset_factory
from .forms import IssuanceForm
from .models import Product  # 替换成你的产品模型

def issuance_view(request):
    products_info = Product.objects.all()  # 你的产品查询逻辑
    # 生成Formset,数量和产品列表一致
    IssuanceFormSet = formset_factory(IssuanceForm, extra=len(products_info))

    if request.method == 'POST':
        formset = IssuanceFormSet(request.POST)
        if formset.is_valid():
            for form in formset:
                # 可选:只处理勾选过的行
                if form.cleaned_data.get('checked'):
                    issuance = form.save(commit=False)
                    # 从表单获取产品ID并关联到发放记录
                    issuance.product_id = form.cleaned_data['product_id']
                    issuance.save()
            # 处理成功后的跳转或提示
            return redirect('shop:some_success_page')
    else:
        # 初始化Formset,给每个表单传入产品ID的初始值
        initial_data = [{'product_id': product.id} for product in products_info]
        formset = IssuanceFormSet(initial=initial_data)

    # 将产品列表和Formset的表单一一对应传入模板
    context = {
        'products_form_pairs': zip(products_info, formset.forms),
        'issuance_formset': formset
    }
    return render(request, 'your_template.html', context)
  1. 模板中渲染表单和产品信息
    模板里循环配对后的产品和表单,同时必须渲染Formset的管理表单(放在<form>标签内):
<form method="post">
    {% csrf_token %}
    <!-- 必须渲染Formset的管理表单,否则无法正确提交 -->
    {{ issuance_formset.management_form }}

    <table>
        {% for product, form in products_form_pairs %}
        <tr>
            <td>{{ form.checked }}</td>
            <td>
                <a href="#" class="open-modal" data-url="{% url 'shop:item_modal' product.id %}">
                    {{ product.item.name }}
                </a>
            </td>
            <td>{{ form.factory }}</td>
            <!-- 隐藏字段会自动渲染,无需手动添加 -->
            {{ form.product_id }}
        </tr>
        {% endfor %}
    </table>

    <button type="submit">提交</button>
</form>

方法二:模板中手动添加隐藏字段

如果不想修改表单类,可以直接在模板里为每一行添加隐藏字段,注意要符合Formset的字段命名规则:

  1. 视图调整
    视图里无需修改表单类,只需将产品列表和Formset的表单配对传入模板:
from django.forms import formset_factory
from .forms import YourExistingIssuanceForm
from .models import Product

def issuance_view(request):
    products_info = Product.objects.all()
    IssuanceFormSet = formset_factory(YourExistingIssuanceForm, extra=len(products_info))
    formset = IssuanceFormSet() if request.method != 'POST' else IssuanceFormSet(request.POST)

    if request.method == 'POST' and formset.is_valid():
        for idx, form in enumerate(formset):
            if form.cleaned_data.get('checked'):
                issuance = form.save(commit=False)
                # 从POST数据中获取对应行的产品ID
                product_id = request.POST.get(f'form-{idx}-product_id')
                issuance.product_id = product_id
                issuance.save()
        return redirect('shop:some_success_page')

    context = {
        'products_form_pairs': zip(products_info, formset.forms),
        'issuance_formset': formset
    }
    return render(request, 'your_template.html', context)
  1. 模板渲染
    在循环里手动添加隐藏字段,命名格式为form-索引-product_id:
<form method="post">
    {% csrf_token %}
    {{ issuance_formset.management_form }}

    <table>
        {% for idx, (product, form) in enumerate(products_form_pairs) %}
        <tr>
            <td>{{ form.checked }}</td>
            <td>
                <a href="#" class="open-modal" data-url="{% url 'shop:item_modal' product.id %}">
                    {{ product.item.name }}
                </a>
            </td>
            <td>{{ form.factory }}</td>
            <!-- 手动添加隐藏字段,对应Formset的命名规则 -->
            <input type="hidden" name="form-{{ idx }}-product_id" value="{{ product.id }}">
        </tr>
        {% endfor %}
    </table>

    <button type="submit">提交</button>
</form>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:48:20