Ошибка валидации формы django
Форма detail_basic_data.html рендерится без проблем. В функции detail_basic_data при любом заполнении формы и сохранении в БД срабатывает else 'Форма неверно заполнена!'. Видимо форма не проходит валидацию. Вопрос что я делаю не так в этом коде? Спасибо.
views.py
def detail_basic_data(request, d_id):
bd_model = get_object_or_404(BasicDataModel, pk=d_id)
if (bd_model.task.user == request.user) or request.user.has_perm('apprise_app.view_task'):
if not bd_model.is_filled:
if request.method == 'POST':
bd_form = BasicDataForm(request.POST)
if bd_form.is_valid():
bd_form.save()
bd_model = get_object_or_404(BasicDataModel, pk=d_id)
bd_model.is_filled = True
bd_model.save()
messages.success(request, 'Форма успешно заполнена!')
return redirect('show-basic-data')
else:
messages.error(request, 'Форма неверно заполнена!')
return redirect('show-basic-data')
bd_form = BasicDataForm(initial={'bd_model': bd_model})
return render(request, 'apprise_app/main/detail_basic_data.html',
{'bd_form': bd_form})
else:
basic_data = BasicData.objects.filter(bd_model=bd_model).last()
return render(request, 'apprise_app/main/detail_bd_filled.html', {'basic_data': basic_data})
else:
raise PermissionError
def show_basic_data(request):
basic_data = BasicDataModel.objects.all()
return render(request, 'apprise_app/main/basic_data.html', {'basic_data': basic_data})
models.py
class BasicDataModel(models.Model):
task = models.ForeignKey(Task, on_delete=models.CASCADE)
is_filled = models.BooleanField(default=False)
def __str__(self):
return self.task.title
class Meta:
verbose_name = 'Модель основных данных'
verbose_name_plural = 'Модель основных данных'
class BasicData(models.Model):
bd_model = models.ForeignKey(BasicDataModel, on_delete=models.CASCADE)
name_report = models.CharField(max_length=150)
report_number = models.CharField(max_length=50)
date_report = models.DateField()
basis_for_evaluation = models.CharField(max_length=500)
object_of = models.CharField(max_length=150)
composition = models.TextField()
purpose = models.CharField(max_length=500)
use_obj = models.CharField(max_length=500)
price_type = models.CharField(max_length=100)
date_rent_estimate = models.DateField()
date_inspection = models.DateField()
range_limits = models.CharField(max_length=100)
org_legal_form = models.CharField(max_length=500, blank=True, null=True)
full_name = models.CharField(max_length=200, blank=True, null=True)
OGRN = models.CharField(max_length=200, blank=True, null=True)
date_assignment_OGRN = models.DateField(blank=True, null=True)
last_name = models.CharField(max_length=100, blank=True, null=True)
first_name = models.CharField(max_length=100, blank=True, null=True)
mid_name = models.CharField(max_length=100, blank=True, null=True)
identity_document = models.CharField(max_length=1000, blank=True, null=True)
location_leg = models.CharField(max_length=250, blank=True, null=True)
location_ind = models.CharField(max_length=250, blank=True, null=True)
documents = models.TextField()
class Meta:
verbose_name = 'Основные данные'
verbose_name_plural = 'Основные данные'
forms.py
class BasicDataForm(forms.ModelForm):
bd_model = forms.ModelChoiceField(queryset=BasicDataModel.objects.all(), widget=HiddenInput())
name_report = forms.CharField(label='Название отчета об оценке')
report_number = forms.CharField(label='Номер отчета об оценке')
date_report = forms.DateField(label='Дата составления отчета (Формат: дд-мм-гггг)',
input_formats=settings.DATE_INPUT_FORMATS)
basis_for_evaluation = forms.CharField(label='Основание для проведения оценки')
object_of = forms.CharField(label='Объект оценки')
composition = forms.CharField(label="Состав объекта оценки", help_text="", widget=forms.Textarea())
purpose = forms.CharField(label='Цель оценки')
use_obj = forms.CharField(label='Предполагаемое использование объекта оценки')
price_type = forms.CharField(label='Вид стоимости')
date_rent_estimate = forms.DateField(label='Дата оценки (Формат: дд-мм-гггг)',
input_formats=settings.DATE_INPUT_FORMATS)
date_inspection = forms.DateField(label='Дата обследования объекта оценки (Формат: дд-мм-гггг)',
input_formats=settings.DATE_INPUT_FORMATS)
range_limits = forms.CharField(label='Границы диапазона РС')
org_legal_form = forms.CharField(label='Организационно правовая форма', required=False)
full_name = forms.CharField(label='Полное наименование', required=False)
OGRN = forms.CharField(label='ОГРН', required=False)
date_assignment_OGRN = forms.DateField(label='Дата присвоения ОГРН', input_formats=settings.DATE_INPUT_FORMATS,
required=False)
last_name = forms.CharField(label='Фамилия', required=False)
first_name = forms.CharField(label='Имя', required=False)
mid_name = forms.CharField(label='Отчество', required=False)
identity_document = forms.CharField(label='Документ удостоверяющий личность', required=False)
location_leg = forms.CharField(label='Адрес места нахождения', required=False)
location_ind = forms.CharField(label='Адрес места нахождения', required=False)
documents = forms.CharField(label="Правоустанавливающие документы", help_text="", widget=forms.Textarea())
class Meta:
model = BasicData
fields = "__all__"
urls.py
urlpatterns = [
path('basicdata/', views.show_basic_data, name='show-basic-data'),
path('basicdata/<int:d_id>/', views.detail_basic_data, name='detail-basic-data'),]
admin.py
admin.site.register(BasicData)
admin.site.register(BasicDataModel)
templates
detail_basic_data.html
{% extends 'apprise_app/main/main_index.html' %}
{% load crispy_forms_tags %}
{% block title %}Основные данные{% endblock %}
{% block content %}
<div class="container text-center profile-dark">
<form method="post" id="myform" enctype="multipart/form-data">
{% csrf_token %}
{{ bd_form.bd_model }}
{{ bd_form.report_number|as_crispy_field }}
{{ bd_form.name_report|as_crispy_field }}
<div class="form-check form-switch">
<input class="form-check-input" name="leg_form" type="checkbox" data-bs-toggle="collapse" data-bs-target="#legform">
<label class="form-check-label" for="mySwitch" style="font-family: 'JetBrains Mono'">Юридическое лицо</label>
</div><br>
<div id="legform" class="collapse">
{{ bd_form.org_legal_form|as_crispy_field }}
{{ bd_form.full_name|as_crispy_field }}
{{ bd_form.OGRN|as_crispy_field }}
{{ bd_form.date_assignment_OGRN|as_crispy_field }}
{{ bd_form.location_leg|as_crispy_field }}
</div><br>
<div class="form-check form-switch">
<input class="form-check-input" name="ind_form" type="checkbox" data-bs-toggle="collapse" data-bs-target="#indform">
<label class="form-check-label" for="mySwitch" style="font-family: 'JetBrains Mono'">Физическое лицо</label>
</div><br>
<div id="indform" class="collapse">
{{ bd_form.last_name|as_crispy_field }}
{{ bd_form.first_name|as_crispy_field }}
{{ bd_form.mid_name|as_crispy_field }}
{{ bd_form.identity_document|as_crispy_field }}
{{ bd_form.location_ind|as_crispy_field }}
</div><br>
{{ bd_form.date_report|as_crispy_field }}
{{ bd_form.basis_for_evaluation|as_crispy_field }}
{{ bd_form.object_of|as_crispy_field }}
{{ bd_form.composition|as_crispy_field }}
{{ bd_form.purpose|as_crispy_field }}
{{ bd_form.use_obj|as_crispy_field }}
{{ bd_form.price_type|as_crispy_field }}
{{ bd_form.date_rent_estimate|as_crispy_field }}
{{ bd_form.date_inspection|as_crispy_field }}
{{ bd_form.range_limits|as_crispy_field }}
{{ bd_form.documents|as_crispy_field }}
<button type="submit" class="btn btn-success rounded">Сохранить</button>
</form>
</div>
{% endblock %}
basic_data.html
{% extends 'apprise_app/main/main_index.html' %}
{% load crispy_forms_tags %}
{% block title %}Основные данные{% endblock %}
{% block content %}
<div class="container text-center">
<table class="table table-dark" style="margin-left: auto; margin-right: auto;">
<thead>
<tr>
<th scope="col" style="font-family: 'JetBrains Mono'">Наименование задачи</th>
<th scope="col" style="font-family: 'JetBrains Mono'">Статус</th>
</tr>
</thead>
<tbody>
{% if perms.apprise_app.view_task %}
{% for element in basic_data %}
<tr>
<td style="font-family: 'JetBrains Mono'"><a style="color:#ffffff;"
href="{% url 'detail-basic-data' element.id %}">{{ element.task.title }}</a>
</td>
{% if element.is_filled %}
<td style="color: lightgreen; font-family: 'JetBrains Mono'">Заполнено</td>
{% else %}
<td style="color: lightcoral; font-family: 'JetBrains Mono'">Не заполнено</td>
{% endif %}
</tr>
{% endfor %}
{% else %}
{% for element in basic_data %}
{% if element.task.user == request.user %}
<tr>
<td style="font-family: 'JetBrains Mono'"><a style="color:#ffffff;"
href="{% url 'detail-basic-data' element.id %}">{{ element.task.title }}</a>
</td>
{% if element.is_filled %}
<td style="color: lightgreen; font-family: 'JetBrains Mono'">Заполнено</td>
{% else %}
<td style="color: lightcoral; font-family: 'JetBrains Mono'">Не заполнено</td>
{% endif %}
</tr>
{% endif %}
{% endfor %}
{% endif %}
</tbody>
</table>
</div>
{% endblock %}
detail_bd_filled.html
{% extends 'apprise_app/main/main_index.html' %}
{% load crispy_forms_tags %}
{% block title %}Основные данные{% endblock %}
{% block content %}
<div class="container text-center" style="font-family: 'JetBrains Mono'">
<h3>{{ basic_data.bd_model.task.title }}</h3>
<p>Название отчета об оценке: {{ basic_data.name_report }} </p>
<p>Номер отчета об оценке: {{ basic_data.report_number }} </p>
{% if basic_data.org_legal_form and basic_data.full_name and basic_data.OGRN and basic_data.date_assignment_OGRN and basic_data.location_leg %}
<p>Заказчик:</p>
<p>Организационно правовая форма: {{ basic_data.org_legal_form }} </p>
<p>Полное наименование: {{ basic_data.full_name }} </p>
<p>ОГРН: {{ basic_data.OGRN }} </p>
<p>Дата присвоения ОГРН: {{ basic_data.date_assignment_OGRN }} </p>
<p>Адрес места нахождения: {{ basic_data.location_leg }} </p>
{% else %}
<p>Заказчик:</p>
<p>Фамилия: {{ basic_data.last_name }} </p>
<p>Имя: {{ basic_data.first_name }} </p>
<p>Отчество: {{ basic_data.mid_name }} </p>
<p>Удостоверение личности: {{ basic_data.identity_document }}" </p>
<p>Адрес места нахождения: {{ basic_data.location_ind }} </p>
{% endif %}
<p>Дата составления отчета: {{ basic_data.date_report }} </p>
<p>Основание для проведения оценки: {{ basic_data.basis_for_evaluation }} </p>
<p>Объект оценки: {{ basic_data.object_of }} </p>
<p>Состав объекта оценки: {{ basic_data.composition }} </p>
<p>Цель оценки: {{ basic_data.purpose }}</p>
<p>Предполагаемое использование объекта оценки: {{ basic_data.use_obj }}</p>
<p>Вид стоимости: {{ basic_data.price_type }}</p>
<p>Дата оценки: {{ basic_data.date_rent_estimate }}</p>
<p>Дата обследования объекта оценки: {{ basic_data.date_inspection }}</p>
<p>Границы диапазона РС: {{ basic_data.range_limits }}</p>
</div>
{% endblock %}