Почему этот набор форм django внезапно перестал сохранять содержимое?

#django #django-forms #formset

#django #django-forms #набор форм

Вопрос:

У меня было это представление, которое отображало форму и набор форм в одном шаблоне:

 class LearnerUpdateView(LearnerProfileMixin, UpdateView):
    model = User
    form_class = UserForm
    formset_class = LearnerFormSet
    template_name = "formset_edit_learner.html"
    success_url = reverse_lazy('pages:home')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        learner = User.objects.get(learner=self.request.user.learner)
        formset = LearnerFormSet(instance=learner)
        context["learner_formset"] = formset
        return context

    def get_object(self, queryset=None):
        user = self.request.user
        return user

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        user = User.objects.get(learner=self.get_object().learner)
        formsets = LearnerFormSet(self.request.POST, request.FILES, instance=user)

        if form.is_valid():
            for fs in formsets:
                if fs.is_valid():
                    # Messages test start
                    messages.success(request, "Profile updated successfully!")
                    # Messages test end
                    fs.save()
                else:
                    messages.error(request, "It didn't save!")
                
            return self.form_valid(form)
        return self.form_invalid(form)
 

Затем я захотел сделать его красивее и добавил виджет select2 multicheckbox и django-bootstrap-datepicker-plus

В других местах ничего не изменилось, но когда я отправляю сообщение, оно сохраняет только данные, относящиеся к пользователю, а не к учащемуся (который полагается на набор форм).

Согласно сообщениям, данные набора форм не проверены, я не понимаю почему, поскольку я вообще не касался сути, а только внешнего вида.

Будучи новичком, я, вероятно, упускаю что-то важное, я заранее благодарю всех, кто может помочь мне разобраться в проблеме.

Здесь ниже формы и шаблон:

(пользователи.формы)

форма для учащихся класса(формы.ModelForm):

     class Meta:
        model = Learner
        fields = ['locations', 'organization', 'supervisor', 'intro']


class UserForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['username', 'first_name', 'last_name', 'birthday', 'email', 'profile_pic']
        widgets = {
            'birthday': DatePickerInput(format='%Y-%m-%d'), }


LearnerFormSet = inlineformset_factory(User, Learner, form=LearnerForm)
 

шаблон

 {% extends '_base.html' %}

{% load crispy_forms_tags %}

{% block content %}

<form action="" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form|crispy }}
    {{ learner_formset.management_form}}

    {% for form in learner_formset %}
        {% if forloop.first  %}
            {% for field in form.visible_fields %}
                {% if field.name != 'DELETE' %}
                    <label for="id_{{ field.name }}">{{ field.label|capfirst }}</label>
                    <div id='id_{{ field.name }}' class="form-group">
                        {{ field.errors.as_ul }}
                        {{ field }}
                    </div>
                {% endif %}
            {% endfor %}
        {% endif %}
    {% endfor %}

    <input class="btn btn-success" type="submit" value="Update"/>
</form>
{% endblock content %}
 

Ответ №1:

Я понял это, вычесав предыдущие коммиты. Проблема была в шаблоне, набор форм не проверялся, потому что я проигнорировал скрытые поля, которые, как я слышал, являются распространенной проблемой при работе с наборами форм.

Итак, правильный код как таковой:

 {% extends '_base.html' %}

{% load crispy_forms_tags %}

{% block content %}

<form action="" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form|crispy }}
    {{ learner_formset.management_form}}

        {% for form in learner_formset %}
            {% if forloop.first %}

            {% comment %} This makes it so that it doesnt show the annoying DELETE checkbox {% endcomment %}
                {% for field in form.visible_fields %}
                    {% if field.name != 'DELETE' %}
                        <label for="{{ field.name }}">{{ field.label|capfirst }}</label>
                        <div id="{{ field.name }}" class="form-group">
                            {{ field }}
                            {{ field.errors.as_ul }}
                        </div>
                    {% endif %}
                {% endfor %}

            {% endif %}

            {% for field in form.visible_fields %}
                {% if field.name == 'DELETE' %}
                    {{ field.as_hidden }}
                {% else %}
       
                    {# Include the hidden fields in the form #}
                    {% if forloop.first %}
                        {% for hidden in form.hidden_fields %}
                            {{ hidden }}
                        {% endfor %}
                    {% endif %}
                    

                    
           
                {% endif %}

            {% endfor %}
   
        {% endfor %}

  

    <input class="btn btn-success" type="submit" value="Update"/>
</form>
{% endblock content %}