Лёзин Арсений, [email protected]
Процесс проверки входных данных на соответствие заданным условиям и ограничениям
- Формы
- Валидаторы
Задачи которые выполняют формы
- Подготовить данные для рендеринга в шаблоны
- Создать HTML-форму с данными
- Получить, провалидировать данные и модифицировать данные для дальнейшего использования
- Обычные формы
forms.Form
- Формы для моделей
forms.ModelForm
forms.py
from django imports forms
class UserForm(forms.Form):
name = forms.CharField(
label='User name',
max_length=100
)
Преобразуется в
<label for="name">User name:</label>
<input id="name" type="text" name="name" maxlength="100" required />
views.py
from .forms import UserForm
def get_name(request):
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
...
else:
form = UserForm()
return render(request, 'name.html', {'form': form})
name.html
<form action='/get-name/' method='POST'>
{% csrf_token %}
{{ form }}
<input type="submit" value="Получить" />
</form>
- form.is_valid() проверяет валидность входных данных формы
- request.method возвращает тип запроса (GET, POST, PUT, DELETE, OPTIONS, PATCH ...)
- request.POST содержит в себе 'десериализованное тело запроса'
- Для преобразования формы в html достаточно вывести ее в шаблоне
- form.cleaned_data - содержит в себе объект из которого мы можем получить по ключу - значение
- {% csrf_token %} - шаблонный тег который добавляет
<input type='hidden' name='csrf_token' value='...' />
- Валидации
- Изменения
forms.py
from django imports forms
BAD_NAMES = [...]
class UserForm(forms.Form):
name = forms.CharField(label='User name', max_length=100)
def clean_name(self):
name = self.cleaned_data['name']
if name in BAD_NAMES:
raise forms.ValidationError(
'Выберите другое имя'
)
return name
- После того как в clean_* методе произошло исключение ValidationError, текст ошибки помещается в словарь
form.errors
под ключиком field-а - В случае если произошла ошибка и form.errors не пустой то
form.is_valid()
возвращает False
- BooleanField
- CharField
- ChoiceField
- DateField
- DateTimeField
- DecimalField
- EmailField
- FileField
- FloatField
- ImageField
- IntegerField
- GenericIPAddressField
- NullBooleanField
- URLField
Пример:
from django.core.exceptions import ValidationError
from django.db import models
def validate_even(value):
if value % 2 != 0:
raise ValidationError('Oooops')
class MyForm(form.Form):
even_field = forms.IntegerField(validators=[validate_even])
class MyModel(models.Model):
even_field = models.IntegerField(
validators=[validate_even]
)
Виджеты это объекты которые отвечают за то как поля формы будут отображаться в HTML
from django import forms
class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField(widget=forms.Textarea)
- https://docs.djangoproject.com/en/2.0/topics/forms/
- https://docs.djangoproject.com/en/2.0/ref/forms/widgets/
- https://docs.djangoproject.com/en/2.0/ref/validators/
Классы форм которые конструируются на базе класса модели
models.py
class Author(models.Model):
name = models.CharField(max_length=100)
birth_date = models.DateField(blank=True, null=True)
forms.py
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = ['name']
...
- model(Обязательное свойство) - класс модели на основе которой конструируется форма
- fields - Список полей которые будут включены в форму из модели или
__all__
- exclude - Список полей которые нужно исключить, удобно использовать если не указали fields, но !опасно! если добавятся еще поля
- widgets - словарь имя_поля: виджет, замена стандартных виджетов
- error_messages - перегрузка стандартных сообщений
class PartialAuthorForm(ModelForm):
class Meta:
model = Author
exclude = ['title']
class AuthorForm(ModelForm):
class Meta:
model = Author
fields = ('name', 'birth_date')
widgets = {
'name': Textarea(
attrs={'cols': 80, 'rows': 20}
),
}
from django.core.exceptions import NON_FIELD_ERRORS
from django.forms import ModelForm
class ArticleForm(ModelForm):
class Meta:
error_messages = {
NON_FIELD_ERRORS: {
'unique_together': "%(model_name)s's %(field_labels)s are not unique.",
},
'title': {
'max_length': 'Слишком длинный заголовок для статьи'
}
}
- labels
labels = {
'name': 'Имя',
}
- help_texts
help_texts = {
'name': 'Это подсказка така информативная',
}
Метод save()
создает и сохраняет объект в базу. Если объект был передан в форму через instance=
в конструкторе, то форма конструируется на основе переданого объекта и обновляется в случае сохранения формы