Django视图中创建Formset时如何关联UI中的评价方法信息
没问题,Formset完全能搞定这个场景,而且结合Django的类视图也非常顺畅。我给你一步步拆解实现方案,保证清晰好懂:
1. 先定义自定义表单
我们需要给每个打分表单加一个隐藏字段,用来存储对应的QualitativeEvaluationMethod的ID,这样提交后就能精准关联到对应的评价方法。代码如下:
from django import forms from .models import QualitativeEvaluation, QualitativeEvaluationMethod class QualitativeEvaluationForm(forms.ModelForm): # 隐藏字段存储评价方法ID,提交时自动携带 evaluation_method_id = forms.IntegerField(widget=forms.HiddenInput()) class Meta: model = QualitativeEvaluation fields = ['score'] # 这里替换成你实际的打分字段名,比如value
2. 创建Formset类
用Django自带的formset_factory生成表单集合,注意设置extra=0,因为我们不需要额外的空表单,每个评价方法对应一个表单就够了:
from django.forms import formset_factory QualitativeEvaluationFormSet = formset_factory( QualitativeEvaluationForm, extra=0 )
3. 实现基于类的视图(FormView)
我们用FormView来处理GET和POST请求,核心是在GET时给每个表单注入对应的评价方法ID,POST时验证表单并创建关联的模型对象:
from django.views.generic.edit import FormView from django.urls import reverse_lazy from django.shortcuts import get_object_or_404 from .models import Employee, QualitativeEvaluationMethod, QualitativeEvaluation class EvaluationSubmitView(FormView): template_name = 'your_evaluation_template.html' # 替换成你的模板路径 form_class = QualitativeEvaluationFormSet success_url = reverse_lazy('evaluation_success') # 提交成功后的跳转页面 def get_form_kwargs(self): kwargs = super().get_form_kwargs() # 获取当前要评价的员工(假设员工ID从URL参数传递,比如url里的<employee_id>) # 同时获取所有需要用到的评价方法,你可以根据业务逻辑筛选,比如只取当前员工适用的方法 evaluation_methods = QualitativeEvaluationMethod.objects.all() # 给formset设置初始数据,每个表单对应一个评价方法的ID kwargs['initial'] = [ {'evaluation_method_id': method.id} for method in evaluation_methods ] return kwargs def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 把评价方法列表传到模板,方便显示方法名称 evaluation_methods = QualitativeEvaluationMethod.objects.all() # 把表单和对应的评价方法配对,模板里用起来更方便 context['evaluation_pairs'] = zip(context['formset'], evaluation_methods) return context def form_valid(self, formset): # 处理表单提交逻辑 # 获取当前评价的员工 employee = get_object_or_404(Employee, id=self.kwargs['employee_id']) # 遍历每个表单,创建QualitativeEvaluation对象 for form in formset: if form.is_valid(): method_id = form.cleaned_data['evaluation_method_id'] evaluation_method = QualitativeEvaluationMethod.objects.get(id=method_id) # 创建模型对象,关联员工和评价方法 QualitativeEvaluation.objects.create( employee=employee, evaluation_method=evaluation_method, score=form.cleaned_data['score'] # 替换成你的打分字段名 ) return super().form_valid(formset)
4. 调整前端模板
原来的表格要改成渲染formset的表单,记得一定要包含formset.management_form(这是formset正常工作的核心),然后配对显示评价方法名称和打分输入框:
<form method="post"> {% csrf_token %} {{ formset.management_form }} <!-- 必须添加,Formset的管理字段 --> <table> <thead> <tr> <td>Evaluation method</td> <td>Value</td> </tr> </thead> <tbody> {% for form, method in evaluation_pairs %} <tr> <td>{{ method.name }}</td> <td> {{ form.score }} <!-- 打分输入框 --> {{ form.evaluation_method_id }} <!-- 隐藏字段,不要遗漏 --> <!-- 显示表单错误(可选) --> {% if form.score.errors %} <div class="text-red-500">{{ form.score.errors.0 }}</div> {% endif %} </td> </tr> {% endfor %} </tbody> </table> <input type="submit" name="submit" value="Submit" id="submit-for-evaluations"/> </form>
替代方案(可选)
如果觉得formset有点重,也可以用单个表单动态生成字段:比如给每个评价方法生成一个score_{method_id}的字段,提交后在视图里遍历这些字段,拆分出方法ID和分数,再创建模型对象。但这种方式需要手动处理字段生成和验证,不如formset规范,维护成本更高,所以还是更推荐用formset方案。
内容的提问来源于stack exchange,提问作者Mahdieh Brf
相关产品推荐
相关产品推荐

