Django Dynami c Formset UpdateView не обновляется - PullRequest
1 голос
/ 06 января 2020

Я использовал этот учебник для успешной настройки динамического c встроенного набора форм с использованием 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})

1 Ответ

1 голос
/ 06 января 2020

Это плохая запись в блоге, потому что ошибки не отображаются, если какая-либо из встроенных форм недействительна. Как пользователь, я не ожидал бы, что представление просто игнорирует ошибки в встроенных формах, успешно сохраняя мой основной экземпляр и не сообщая об этих ошибках.

Обратите внимание, что я не знаю, что это за ошибки , может быть, это просто проблема с формой управления. Но в любом случае, ошибки набора форм должны быть обработаны за до , когда главный объект действительно сохранен.

В общем, если вам нужно написать представление с несколькими формами (включая набор форм), это Лучше использовать представление на основе функций или View, где вы пишете get и post, чем пытаться принудительно преобразовать это в обобщенное c представление на основе классов, которое не предназначено для этого.

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})

Таким образом, ваш шаблон может отображать ошибки каждой формы, включая ошибки в наборе форм. Как упоминалось ранее, вы также можете сделать это в View (чтобы ваши миксины работали), просто напишите методы get и post и верните то же самое, что и в представлении функций на основе выше.

...