Django modelformset не сохраняет данные. Возвращает пустой список после вызова clean_data

У меня проблема с набором форм, он не сохраняется. Консоль не выдает ошибок, но после вызова print(formset.cleaned_data) возвращает пустой список. Стандартная форма сохраняется нормально. Этот набор форм предназначен для добавления услуги, сделанной для объекта автомобиля. Я не смог найти ответ в интернете, может кто-то поможет или найдет лучшее решение.

models.py

class Car(models.Model):
    FUEL = (
        ('', '---------'),
        ('1', 'Gasoline'),
        ('2', 'Diesel'),
        ('3', 'Electric'),
        ('4', 'Hybrid'),
    )

    client = models.ForeignKey(Client,on_delete=models.CASCADE, null=True, blank=True)
    car_make = models.ForeignKey(CarMake, on_delete=models.CASCADE)
    car_model = models.ForeignKey(CarModel, on_delete=CASCADE)
    fuel_type = models.CharField(max_length=15, choices=FUEL, default=None)
    engine = models.CharField(max_length=15)
    extra_info = models.TextField(max_length=300, verbose_name='Remarks', null=True, blank=True)
    date_added = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return f"{self.client} | {self.car_make} {self.car_model}"
    
    class Meta:
        ordering = ('-date_updated',)
    

class Service(models.Model):
    car_relation = models.ForeignKey(Car, on_delete=models.CASCADE)
    service_name = models.CharField(max_length=200, verbose_name='Service')
    service_price = models.CharField(verbose_name='Price', blank=True, null=True, max_length=20)

    def __str__(self):
        return self.service_name

forms.py

class AddServiceForm(forms.ModelForm):
    class Meta:
        model = models.Service
        fields = ['service_name']

class CarForm(forms.ModelForm):
    class Meta:
        model = models.Car
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['car_model'].queryset = models.CarModel.objects.none() # returns no value till "Make" field is chosen, will be negated in elif statement

        if 'car_make' in self.data:
            try:
                car_make_id = int(self.data.get('car_make'))
                self.fields['car_model'].queryset = models.CarModel.objects.filter(make_id=car_make_id).order_by('model_name')
            except (ValueError, TypeError):
                pass
        elif self.instance.pk:
            self.fields['car_model'].queryset = self.instance.car_make.carmodel_set.order_by('model_name') # this negates the init overwrite

views.py

def car_create_view(request):
    ServiceFormset = modelformset_factory(Service, form=AddServiceForm, extra=0)
    formset = ServiceFormset
    if request.method == 'POST':
        form = CarForm(request.POST or None)
        formset = ServiceFormset(request.POST or None)
        if all([form.is_valid(), formset.is_valid()]):
            form.save()
            for f in formset:
                f.save()
            print(form, form.cleaned_data)
            print(formset, formset.cleaned_data)
        else:
            return HttpResponse('Something went wrong.')
            
    else:
        form = CarForm()
        formset = ServiceFormset
    return render(request, 'san_diego/car.html', {'carform': form, 'formset': formset})

шаблон

<form action='' method='post' id='carForm' data-carmodels-url="{% url 'ajax_load_car_models' %}">
    {% csrf_token %}
    {{ carform|crispy }}
    {% if formset %}
        <h3>Formset</h3>
        {{formset.management_form}}
        <div id='service-form-list'>
            <div class='service-form'>
                {{formset.form|crispy}} 
            </div>
        </div>
    
        <div id='empty-form' class='hidden'>{{formset.empty_form|crispy}}</div>
        <button id='add-more' type='button'>Add</button>
        <input type='submit' value='Submit'>
    {% endif %}
</form>

С помощью formset = ServiceFormset вы не инстанцируете набор форм в вашем views.py, а определяете класс FormSet.

Используйте formset = ServiceFormset() для инстанцирования набора форм. Это позволит вам выполнять итерации по нему.

Вернуться на верх