Django. Проблема с выводом ошибки при неверно введенных данных в поле формы
Столкнулся со следующей проблемой. При вводе неверных данных текст ошибки выводится в неверном формате, перепробовал уже кучу всего, ничего не помогает. На картинке ниже видно в чем проблема.
В forms.py прописываю функцию check_if_there_are_any_repeats_of_unique_fields(), которая должна менять текст ошибки, но при запуске она как будто не отрабатывает. Может кто знает в чем может быть дело?
views.py
def building_form(request, id = 0): # insert operation
if request.method == "GET":
if id == 0:
form = BuildingsForm(initial={'id': buildings_id_autofill()})
else:
building = Buildings.objects.get(pk=id)
form = BuildingsForm(instance=building)
return render(request, "database/buildings/buildings_form.html", {'form': form})
else:
if id == 0:
form = BuildingsForm(request.POST)
else:
building = Buildings.objects.get(pk=id)
form = BuildingsForm(request.POST, instance=building)
if form.is_valid():
form.save()
building_name = form.cleaned_data.get('building_name')
messages.success(request, 'Здание с именем "' + building_name + '" было успешно добавлено в базу данных.')
else:
# errors = form.errors
# print(errors)
return render(request, "database/buildings/buildings_form.html", {'form': form})
return redirect('/add_new_building/')
filters.py
class BuildingFilter(df.FilterSet):
name = df.CharFilter(field_name='building_name', label='Имя здания', lookup_expr='icontains')
descr = df.CharFilter(field_name='description', label='Примечание', lookup_expr='icontains')
coords = df.CharFilter(field_name='coordinates', label='Координаты', lookup_expr='icontains')
addr = df.CharFilter(field_name='address', label='Адрес', lookup_expr='icontains')
class Meta:
model = Buildings
fields = ['name', 'facility_id', 'coords', 'addr', 'descr']
models.py
class Buildings(models.Model):
id = models.CharField(max_length=4, primary_key=True, blank=True)
building_name = models.CharField(max_length=15, unique=True)
facility_id = models.ForeignKey(Facilities, on_delete=models.CASCADE)
coordinates = models.CharField(max_length=80, null=True)
address = models.CharField(max_length=100, null=True)
description = models.CharField(max_length=200, null=True)
class Meta:
ordering = ["building_name"]
def __str__(self):
return self.building_name
forms.py
class BuildingsForm(forms.ModelForm):
class Meta:
model = Buildings
fields = '__all__' #['building_name', 'facility_id', 'coordinates', 'address', 'description']
labels = {
'id': 'Уникальный идентификатор',
'building_name': 'Имя здания',
'facility_id': 'Название предприятия',
'coordinates': 'Координаты здания (опционально)',
'address': 'Адрес здания (опционально)',
'description': 'Комментарий (опционально)',
}
def __init__(self, *args, **kwargs):
super(BuildingsForm, self).__init__(*args, **kwargs)
self.fields['facility_id'].empty_label = "Выберите предприятие..."
self.fields['id'].widget.attrs['placeholder'] = "Пример (eng): B1337"
self.fields['id'].widget = forms.HiddenInput()# скрываем поле id для пользователя
self.fields['building_name'].widget.attrs['placeholder'] = "Пример: стр.1337"
self.fields['coordinates'].required = False
self.fields['address'].required = False
self.fields['description'].required = False
def check_if_there_are_any_repeats_of_unique_fields(self):
# b = Buildings.objects.all()
building_name = self.cleaned_data.get('building_name')
for instance in Buildings.objects.all():
if building_name in instance:
# Здесь также пробовал строку "raise forms.ValidateError..." Также не сработало
self.add_error('building_name', "Имя '" + building_name + "'уже есть в базе данных. Введите другое имя.")
return building_name
html.html
{% extends "database/base.html" %}
{% load crispy_forms_tags %}
{% include 'https://getbootstrap.com/docs/4.0/components/alerts/' %}
{% block title %}Добавление в БД{% endblock %}
{% block content %}
<div class="boss col-md-10 offset-md-2">
<div class="jumbotron">
<h1 class="display-6 font-weight-bold align-center mt-n3">Добавление нового здания в БД</h1>
<hr class="my-4">
<form action="" method="post" autocomplete="off" id="fff">
{% csrf_token %}
{{ form|crispy }}
{{ form.errors }}
{% for message in messages %}
<p id="messages" style="text-align: center; color: darkgreen; font-size: x-large; font-weight: bold">
{{ message }}
</p>
{% endfor %}
<div class="row">
<div class="col-md-8">
<button type="submit" class="btn btn-success btn-block btn-lg"><i class="fas fa-folder-plus"></i> Добавить в БД</button>
</div>
<div class="col-md-4 mb-n3">
<a href="{% url 'building_table' %}" class="btn btn-secondary btn-block btn-lg">
<i class="fa fa-stream"></i> К таблице Здания
</a>
</div>
</div>
</form>
</div>
</div>
{% endblock content %}
Ответы (1 шт):
Автор решения: Andrey Maslov
→ Ссылка
- Для того, что бы названия полей отображались правильно и в label и в списке ошибок не забывай добавлять
verbose_nameдля полей в описании моделиbuilding_name = models.CharField(max_length=15, unique=True, verbose_name="Имя здания") - Ты написал функцию, которая проверяет на уникальность, но не видно, что бы ты где-то пытался ее вызвать.
- По большому счету тебе не нужна это функция, потому, что у тебя в описании поля стоит
unique=Trueи django автоматически будет проверять это поле на уникальность - Если хочешь изменить сообщение об ошибке, когда имя здания не уникально можно сделать так
class BuildingsForm(forms.ModelForm):
...
def __init__(self, *args, **kwargs):
super(BuildingsForm, self).__init__(*args, **kwargs)
...
self.fields['building_name'].error_messages = {
'unique': "Выбранное имя здания уже используется, выберите другое имя",
}
