Django model_formset не может редактировать, сохранять или удалять информацию

Я пытаюсь создать простой modelformset для отображения нескольких копий одной и той же формы. Моя таблица models.py называется Driver и имеет только одно поле, driver:

class Driver(models.Model):
driver = models.CharField(max_length=100, blank=True, null=True)

def __str__(self):
    return self.driver if self.driver else ''

Мой urls.py:

urlpatterns = [
path('driver/', DriverCreateView.as_view(), name = "driver-create"),
]

Мой forms.py:

class DriverForm(forms.ModelForm):
    class Meta:
        model = Driver
        fields = ['driver']
        # exclude = ("id",)

DriverFormSet = modelformset_factory(Driver, form = DriverForm, fields = ['driver'], extra = 1, max_num=20, can_delete=True)

Я почти уверен, что проблема в файле views.py:

class DriverCreateView(LoginRequiredMixin, CreateView):
  model = Driver
  form_class = DriverForm
  template_name = 'trucking/driver_form.html'
  
  def get_context_data(self, **kwargs):
    context = super(DriverCreateView, self).get_context_data(**kwargs)
    context['formset'] = DriverFormSet()
    return context

  def post(self, request, *args, **kwargs):
    formset = DriverFormSet(request.POST)
    form= DriverForm(request.POST)
    if formset.is_valid():
      formset.save()
      if self.request.POST.get('Save_Exit'):
        return HttpResponseRedirect('/database/')
      if self.request.POST.get('Save'):
        return HttpResponseRedirect('/driver/')
    return render(request, self.template_name, {'formset': formset})

Наконец-то мой шаблон driver_form.html:

    <form method = "POST">
        <fieldset class = "form-group">
        {% csrf_token %}
        {{ formset.management_form }}
        {{ formset.non_form_errors }}
        
        {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %}
        <table cellpadding="6" cellspacing="1" border="0">


            <tbody>
        {% for form in formset %}
            {% for field in form.visible_fields %}
            <tr>    
                <td class="column_name">{{field.label_tag}}{{field.auto_id}}</td>
                <td class="column_data">{{field}}</td>
                <td class="column_errors">{{field.errors|striptags}}</td>

            </tr>
            {% endfor %}

        {% endfor %}

            <tr>
                <td colspan = "2" class="column_submit">
                    <input type="submit" name="Save_Exit" value="Save & Exit" class="submit">
                    <input type="submit" name="Save" value="Save" class="submit">
                    <a href="{% url 'database'%}"><input type="button" name="Cancel" value="Cancel" class="submit"></a>
                </td>
            </tr> 
        </tbody>

Причина, по которой я думаю, что дело в файле views.py, заключается в том, что я собрал его из нескольких различных источников, и не уверен, действительно ли строки, которые у меня есть, необходимы, или чего мне не хватает в форме, чтобы действительно обновить информацию. Когда я отредактировал функцию post внутри представления на основе класса на form.save() вместо formset.save(), я смог успешно добавить новые поля, но не обновить или удалить существующие. У меня такое ощущение, что логика каким-то образом не попадает в операторы if, или набор форм сбрасывается на значение по умолчанию, возможно в этой строке:

    context['formset'] = DriverFormSet()

Любой совет будет принят с благодарностью.

Вам не хватает добавления formset скрытых входов. Эти входы обеспечивают Driver.id для каждой формы, так что django будет знать, какой экземпляр обновлять с помощью driver.

Вместо

{% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %}

использовать

{% for form in formset %}
    {% for hidden in form.hidden_fields %}
        {{ hidden }}
    {% endfor %}
{% endfor %}

CreateView (и все представления на основе классов) не предназначены для работы с наборами форм. Они предназначены для работы с одной формой и одним экземпляром модели. У вас будет несколько форм (через набор форм) и несколько экземпляров модели. Ваше представление будет работать, но оно не использует наилучшим образом CreateView: вы не используете несколько методов, которые должны быть использованы, у вас будут self.object и self.form, которые вы никогда не будете использовать в вашем представлении.

В представлениях, основанных на функциях, нет ничего плохого. Обратитесь к django docs. Например:

@login_required
def create_drivers(request):
    if request.method == 'POST':
        formset = DriverFormSet(request.POST, request.FILES)
        if formset.is_valid():
            formset.save()
            if request.POST.get('Save_Exit'):
                return HttpResponseRedirect('/database/')
            if request.POST.get('Save'):
                return HttpResponseRedirect('/driver/')
    else:
        formset = DriverFormSet()
    return render(request, 'trucking/driver_form.html', {'formset': formset})
Вернуться на верх