首页 > 解决方案 > 在 UI 中获取额外信息以在 django 视图中创建表单集

问题描述

我不确定标题是否准确地描述了我想要的东西。我有一个具有 N 评估方法的员工和一个评估器,可以在一页中评估特定员工的每种评估方法,如下所示:

<table>
    <thead>
      <tr>
        <td>Evaluation method</td>
        <td>Value</td>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>evaluation method1</td>
        <td><input id="value_1"/></td>
        </tr> 
        <tr>
        <td>evaluation method2</td>
        <td><input id="value_2"/></td>
        </tr> 
        <tr>
        <td>evaluation method3</td>
        <td><input id="value_3"/></td>
        </tr> 
        <tr>
        <td>evaluation method4</td>
        <td><input id="value_4"/></td>
        </tr> 
     </tbody>
 </table>
<input type="submit" name="submit" value="Submit" id="submit-for-evaluations"/>

我想为每个具有 QualitativeEvaluationMethod 模型的外键的结果创建一个名为 QualitativeEvaluation 的模型对象。我正在对结果使用评估模型的形式集,但我的问题是,当我在视图中创建它们的对象时,我不知道如何将这些结果与它们所在行中的 QualitativeEvaluationMethod 关联起来。我更喜欢使用基于类的视图。使用表单集时有解决方案吗?或者还有其他更简单的方法吗?

标签: djangoviewforeign-keysformsetdjango-class-based-views

解决方案


首先,我为使用表单集定义了一个创建视图:

class FormsetCreateView(CreateView):
    form_class = None
    template_name = None
    data = None
    employee = None

    def __init__(self, **kwargs):
    super().__init__(**kwargs)
    self.object = None

    def get_context_data(self, **kwargs):
    context = super(FormsetCreateView, self).get_context_data(**kwargs)
    if 'form' in kwargs and kwargs['form'].errors:
        context['errors'] = kwargs['form'].errors
    context['employee'] = self.employee
    return context

    def post(self, request, *args, **kwargs):
    if kwargs['formset'].is_valid():
        return self.form_valid(kwargs['formset'])
    else:
        return self.form_invalid(kwargs['formset'])

    def form_valid(self, formset):
    for i in range(len(formset) - 1):
        formset[i].save()
    return super(FormsetCreateView, self).form_valid(formset[len(formset) - 1])

    def form_invalid(self, formset):
    for form in formset:
        if form.errors:
            return super(FormsetCreateView, self).form_invalid(form)

    def get_success_url(self):
    return reverse('app:evaluator_main')

    def set_initial_data(self):
    pass

然后我从我的 FormsetCreateView 继承来添加一些额外的行为:

class QualitativeEvaluationCreateView(FormsetCreateView):
    form_class = QualitativeEvaluationForm
    template_name = 'evaluator/ql_evaluation.html'
    model_class = QualitativeEvaluationMethod
    extra_model = QualitativeEvaluation

    def dispatch(self, request, *args, **kwargs):
    self.employee = get_object_or_404(NormalEmployee, id=int(self.kwargs['eID']))
     //to get employee id from url
    self.data = self.set_initial_data()
    return super().dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
    context = super(QualitativeEvaluationCreateView, self).get_context_data(**kwargs)
    context['formset'] = QualitativeEvaluationFormset(initial=self.data)
    return context

    def post(self, request, *args, **kwargs):
    kwargs['formset'] = QualitativeEvaluationFormset(self.request.POST, initial=self.data)
    return super().post(request, *args, **kwargs)

    def set_initial_data(self):
    evaluation_methods = self.employee.get_unevaluated_qualitative_evaluation_methods()
    return [{'evaluation_method': c, 'employee': self.employee} for c in evaluation_methods]

我的表单和表单集如下:

class QualitativeEvaluationForm(forms.ModelForm):
    class Meta:
    model = QualitativeEvaluation
    fields = ('value', 'evaluation_method', 'employee')
    widgets = {
        'evaluation_method': forms.Select(attrs={'style': 'display:none;'}),
         // set display to none because i will show all evaluation_methods and only get their value so evaluation_method is obvious and i don't need to ask it
        'employee': forms.Select(attrs={'style': 'display:none;'}),
         // set display to none because employee which we are evaluating is obvious and i don't need to ask it
    }
QualitativeEvaluationFormset = formset_factory(QualitativeEvaluationForm, extra=0)

推荐阅读