首页 > 解决方案 > Django Dynamic Formset UpdateView 不更新

问题描述

我使用教程成功地使用 Django 设置了动态内联表单集。CreateView 效果很好,但我无法让 UpdateView 实际更新相关字段。没有抛出错误,但项目不会更新。我相信我已将错误隔离到 form_valid 函数。代码如下。感谢您提供任何帮助。

class ApplicantCreate(CreateView):
    model = Applicant
    success_message = 'Your application was submitted successfully.'
    form_class = forms.ApplicantForm
    template_name = 'careers/add_applicant.html'
    success_url = reverse_lazy('careers:thanks')

    def get_context_data(self, **kwargs):
        data = super(ApplicantCreate, self).get_context_data(**kwargs)
        positions = super(ApplicantCreate, self).get_context_data(**kwargs)
        if self.request.POST:
            data['employer'] = forms.ApplicantEmployerFormSet(
                                    self.request.POST,
                                    prefix='employer')
            data['education'] = forms.ApplicantEducationFormSet(
                                     self.request.POST,
                                     prefix='education')
        else:
            data['employer'] = forms.ApplicantEmployerFormSet(prefix='employer')
            data['education'] = forms.ApplicantEducationFormSet(prefix='education')
        return data
        context['unfilled_positions'] = Position.objects.filter(filled=False)
        return positions

    def form_valid(self, form):
        context = self.get_context_data()
        employer = context['employer']
        education = context['education']
        with transaction.atomic():
            form.instance.created_by = self.request.user
            self.object = form.save()
            if employer.is_valid():
                employer.instance = self.object
                employer.save()
            if education.is_valid():
                education.instance = self.object
                education.save()
        return super(ApplicantCreate, self).form_valid(form)

    def get_success_url(self):
        return reverse_lazy('careers:thanks')

class ApplicantUpdate(SuccessMessageMixin,LoginRequiredMixin,GroupRequiredMixin,UpdateView):
    group_required = [u'careers-admin',u'careers']
    model = Applicant
    success_message = '%(first_name)s %(last_name)s was updated successfully.'
    form_class = forms.ApplicantUpdateForm
    template_name = 'careers/edit_applicant.html'

    def get_context_data(self, **kwargs):
        data = super(ApplicantUpdate, self).get_context_data(**kwargs)
        positions = super(ApplicantUpdate, self).get_context_data(**kwargs)
        if self.request.POST:
            data['employer'] = forms.ApplicantEmployerFormSet(
                                    self.request.POST,
                                    instance=self.object,
                                    prefix='employer')
            data['education'] = forms.ApplicantEducationFormSet(
                                    self.request.POST,
                                    instance=self.object,
                                    prefix='education')
        else:
            data['employer'] = forms.ApplicantEmployerFormSet(
                                    instance=self.object,
                                    prefix='employer')
            data['education'] = forms.ApplicantEducationFormSet(
                                    instance=self.object,
                                    prefix='education')
        return data
        context['unfilled_positions'] = Position.objects.filter(filled=False)
        return positions

    def form_valid(self, form):
        context = self.get_context_data()
        employer = context['employer']
        education = context['education']
        with transaction.atomic():
            form.instance.created_by = self.request.user
            self.object = form.save()
            if employer.is_valid():
                employer.instance = self.object
                employer.save()
            if education.is_valid():
                education.instance = self.object
                education.save()
        return super(ApplicantUpdate, self).form_valid(form)

    def get_success_url(self):
        return reverse_lazy('careers:applicant_detail',kwargs={'pk': self.object.pk})

标签: pythondjangodynamicformset

解决方案


这不是一篇好的博文,因为如果任何内联表单无效,则不会显示错误。作为用户,我不希望视图只是默默地忽略内联表单中的错误,成功保存我的主实例而不报告这些错误。

请注意,我不知道错误是什么,也许这只是管理表格的问题。但无论如何,应该在实际保存主对象之前处理表单集错误。

一般来说,如果您需要编写具有多个表单(包括表单集)的视图,最好使用基于函数的视图或View您编写的地方,getpost不是试图将其强制为基于类的通用视图,即不是为了这个。

def multiple_forms_view(request, object_id):
    # if this is a POST request we need to process the form data
    obj = get_object_or_404(MyModel, pk=object_id)
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = MyForm(request.POST, instance=obj)
        formset = MyFormSet(request.POST, instance=obj, ...)
        # check whether it's valid:
        if form.is_valid() and formset.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect('/thanks/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = MyForm(instance=obj)
        formset = MyFormSet(instance=obj, ...)

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

这样,您的模板可以呈现每个表单的错误,包括表单集中的错误。如前所述,您也可以在 a 中执行此操作View(因此您的 mixins 将起作用),只需编写getandpost方法并返回与上面基于函数的视图中相同的内容。


推荐阅读