Форма не сохраняктся django formset
views.py
def expert_edit(request, pk): """Редактирования данных экспертизы"""
expert = get_object_or_404(Expert, pk=pk)
formset = FileExpertFormset(queryset=ExpertFiles.objects.none())
if request.method == "POST":
expert_form = ExpertNewForm(request.POST, instance=expert)
formset = FileExpertFormset(request.POST, request.FILES)
if expert_form.is_valid() and formset.is_valid():
expert = expert_form.save()
for form in formset:
print(form.as_table())
print(form.instance)
inst = form.save(commit=False)
if inst.scan_doc:
inst.files = expert
inst.save
return redirect('/expert/')
else:
error = ' Форма не верно заполнена'
expert_form = ExpertNewForm(instance=expert)
list_files = expert.files_expert.all()
template_name = 'dist/expert/edit.html'
data = {'expert_edit': expert_form,
'list_files': list_files,
'pk': pk,
'formset': formset,
'error': error
}
return render(request, template_name, data)
models.py
class ExpertFiles(models.Model): """Таблица прикрепленных файлов Экспертизы """
TYPES = (
(1, 'Акт Осмотра'),
(2, 'Экспертиза'),
(3, 'Калькуляция'),
(3, 'Скан чека'),
)
types = models.PositiveSmallIntegerField(
choices=TYPES,
null=True,
default=None,
blank=True,
)
files = models.ForeignKey(
Expert,
on_delete=models.CASCADE,
related_name='files_expert',
blank=True,
null=True,
verbose_name='Прикрепленные файлы (Expert)'
)
description = models.CharField(
max_length=100,
verbose_name='Описание '
)
scan_doc = models.FileField(
upload_to='media/doc_expert/',
null=True,
default=None,
verbose_name="Файл"
)
author = models.OneToOneField(
User,
db_column='user',
on_delete=models.CASCADE,
blank=True,
null=True,
)
created = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
class Meta:
verbose_name = 'Файл Экспертизы'
verbose_name_plural = 'Файлы Экспертизы'
forms.py
FileExpertFormset = modelformset_factory( ExpertFiles, fields=('files', 'types', 'description', 'scan_doc' ), extra=1, widgets={ 'files': TextInput( attrs={ 'class': 'form-control', 'placeholder': 'Файлы Expert' } ), 'types': Select( attrs={ 'class': 'form-control', 'placeholder': 'Тип файла' } ), 'description': TextInput( attrs={ 'class': 'form-control', 'placeholder': 'Описание к файлу' } ), 'scan_doc': FileInput(attrs={ 'class': 'form-control', 'placeholder': 'Файл', } ), } )
edit.html
<form method="POST" action="" class="form-control"
enctype="multipart/form-data">
{% csrf_token %}
<div class="row">
<div class="row">
<hr>
<div class="col-lg-5">
<label class="form-label" for="formrow-firstname-input">Выбор Заказчика</label>
{{ expert_edit.client }}
</div>
<div class="col-lg-5">
<label class="form-label" for="formrow-firstname-input">ТС Заказчика</label>
{{ expert_edit.car }}
</div>
</div>
</div>
<hr>
<div class="row">
<div class="mt-6">
<div class="row">
<div class="col-lg-4">
<div class="mb-3">
<label>Контрагент:</label>
{{ expert_edit.contragent }}
</div>
<div class="mb-3">
<label class="form-label">Стоимость</label>
{{ expert_edit.summa_exp }}
</div>
<div class="mb-3">
<label class="form-label" id="datepicker2" for="formrow-firstname-input">Дата завершение
ЭО</label>
{{ expert_edit.data_out }}
</div>
</div>
<div class="col-lg-6">
<div class="col-md-15">
<div class="col-lg-6">
<label class="form-label" for="formrow-firstname-input">Вид оценки</label>
{{ expert_edit.type }}
</div>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-nowrap table-hover mb-0">
<thead>
<tr>
<th scope="col">№</th>
<th scope="col">Тип расчета</th>
<th scope="col">Сумма</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">01</th>
<td><a href="#" class="text-dark">Востановительный ремонт без износа</a>
</td>
<td>
{{ expert_edit.price_nwear }}
</td>
</tr>
<tr>
<th scope="row">02</th>
<td><a href="#" class="text-dark">Востановительный ремонт с износом</a>
</td>
<td>
{{ expert_edit.price_wwear }}
</td>
</tr>
<tr>
<th scope="row">03</th>
<td><a href="#" class="text-dark">Средняя цена по рынку</a></td>
<td>
{{ expert_edit.price_mmarket }}
</td>
</tr>
<tr>
<th scope="row">04</th>
<td><a href="#" class="text-dark">Годные остатки</a></td>
<td>
{{ expert_edit.price_uleftovers }}
</td>
</tr>
<tr>
<th scope="row">05</th>
<td><a href="#" class="text-dark">Сумма утраченной товарной
стоимости</a>
</td>
<td>
{{ expert_edit.price_uts }}
</td>
<td>
</td>
</tr>
<tr>
<th scope="row">06</th>
<td><a href="#" class="text-dark">Сумма ущерба</a></td>
<td>
{{ expert_edit.price_nwear }}
</td>
</tr>
</tr>
</tbody>
</table>
<div class="row mb-4">
<label class="form-label" for="formrow-firstname-input">Комментарий к экспертному
заключению</label>
{{ expert_edit.comment }}
</div>
<hr>
<h3>Документы Экспертизы</h3>
<div data-repeater-item class="row">
{{ formset.management_form }}
{% for form in formset %}
<div class="row form-row">
<div>
</div>
<div class="mb-3 col-lg-2">
{{ form.types }}
</div>
<div class="mb-3 col-lg-5">
{{ form.description }}
</div>
<div class="mb-3 col-lg-2">
{{ form.scan_doc }}
</div>
<div class="mb-3 col-lg-2">
<button id="minus" type="button"
class="btn btn-success remove-form-row">-
</button>
</div>
</div>
<div class="input-group-append">
<button id="plus" type="button"
class="btn btn-success add-form-row">Добавить
</button>
</div>
{% endfor %}
<div class="col-15">
<ol class="breadcrumb m-0">
<button class="btn btn-primary w-md" type="submit">Сохранить</button>
</ol>
</div>
</div>
</div>
</div>
</div>
</form>
Совсем неплохо будет, если вы будете проверять свои значения и как-то на это реагировать.
class MyException(Exception):
pass
# .......
if request.method == "POST":
expert_form = ExpertNewForm(request.POST, instance=expert)
formset = FileExpertFormset(request.POST, request.FILES)
if expert_form.is_valid() and formset.is_valid():
expert = expert_form.save()
for form in formset:
print(form.as_table())
print(form.instance)
inst = form.save(commit=False)
if inst.scan_doc:
inst.files = expert
inst.save
else:
raise MyException('is not inst.scan_doc')
return redirect('/expert/')
else:
raise MyException(f'expert_form or formset is not valid: {expert_form.errors};{formset.errors}')