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()
для инстанцирования набора форм. Это позволит вам выполнять итерации по нему.