Формы
Создать файл blog/forms.py и добавить формы
from django import forms
from .models import Tag
class TagForm(forms.Form):
title = forms.CharField(max_length=50)
slug = forms.CharField(max_length=50)
def save(self):
new_tag = Tag.objects.create(
title=self.cleaned_data['title'],
slug=self.cleaned_data['slug']
)
return new_tag
Немного теории о cleaned_data
В shell ипортировать класс формы
from blog.forms import TagForm
Создать экземляр класса TagForm
>>> tf = TagForm()
>>> tf
<TagForm bound=False, valid=Unknown, fields=(title;slug)> # bound - есть ли связанные данные (введенные в форму)
Посмотреть список атрибутов
dir(tf) # cleaneв_data - отсутсвует
Проверка связанных данных, валидности и словаря ошибок
>>> tf.is_bound
False
>>> tf.is_valid()
False
>>> tf.errors
{}
Заполнить поля пустыми строками
>>> d = {'title': '', 'slug': ''}
>>> tf = TagForm(d)
>>> tf
<TagForm bound=True, valid=Unknown, fields=(title;slug)>
Ешё раз проверить
>>> tf.is_bound
True
>>> tf.is_valid()
False
>>> tf.errors
{'title': ['This field is required.'], 'slug': ['This field is required.']}
Проверить список атрибутов
>>> dir(tf) # cleaned_data - появился
>>> tf.cleaned_data
{}
Словарь cleaned_data появился, потому что была заполнена форма (tf.is_bound = True), далее вызвался метод is_valid, затем создается словарь. Если is_valid вернул True, то словарь был бы заполнен.
Заполняем поля данными
>>> d = {'title': 'some title', 'slug': 'some-title'}
>>> tf = TagForm(d)
>>> tf.is_valid()
True
>>> tf.errors
{}
>>> tf.cleaned_data
{'title': 'some title', 'slug': 'some-title'}
Теперь данные из словаря cleaned_data можно использовать для создания экземпляра модели
from blog.models import Tag
tag = Tag(title=tf.cleaned_data['title'], slug=tf.cleaned_data['slug'])
tag.save()
Добавить функцию clean_slug
blog/forms.py
from django import forms
from .models import Tag
from django.core.exceptions import ValidationError
class TagForm(forms.Form):
title = forms.CharField(max_length=50)
slug = forms.CharField(max_length=50)
def clean_slug(self):
new_slug = self.cleaned_data['slug'].lower() # сохранять slug в нижнем регистри
if new_slug == 'create':
raise ValidationError('Slug my not be "create"') # валидация slug`a 'create'
return new_slug
def save(self):
new_tag = Tag.objects.create(
title=self.cleaned_data['title'],
slug=self.cleaned_data['slug']
)
return new_tag
Указать шаблон urla`a
blog/utils.py
from django.urls import path
from .views import *
urlpatterns = [
path('', posts_list, name='posts_list_url'),
path('post/<str:slug>/', PostDetail.as_view(), name='post_detail_url'),
path('tags/', tags_list, name='tags_list_url'),
path('tag/create', TagCreate.as_view(), name='tag_create_url'),
path('tag/<str:slug>/', TagDetail.as_view(), name='tag_detail_url')
]
Добавить класс
blog/views.py
--/--/--
--/--/--
from .forms import TagForm
--/--/--
--/--/--
--/--/--
--/--/--
--/--/--
--/--/--
class TagCreate(View):
def get(self, request):
form = TagForm()
return render(request, 'blog/tag_create.html', context={'form': form})
--/--/--
--/--/--}
Создать шаблон
blog/templates/blog/tag_create.html
{% extends 'blog/base_blog.html' %}
{% block title %}
Tag create - {{ block.super
{% endblock %}
{% block content %}
<form action="{% url 'tag_create_url' %}" method="post">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
{% if field.errors %}
<div class="alert alert-danger">
{{ field.errors }}
</div>
{% endif %}
{{ field.label }}
{{ field }}
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">Create Tag</button>
</form>
{% endblock %}
Определить стиль для input`ов
blog/forms.py
--/--/--
--/--/--
--/--/--
title.widget.attrs.update({'class': 'form-control'})
slug.widget.attrs.update({'class': 'form-control'})
--/--/--
--/--/--
Реализовать метод POST
blog/views.py
--/--/--
from django.shortcuts import redirect
--/--/--
class TagCreate(View):
def get(self, request):
form = TagForm()
return render(request, 'blog/tag_create.html', context={'form': form})
def post(self, request):
bound_form = TagForm(request.POST)
if bound_form.is_valid():
new_tag = bound_form.save()
return redirect(new_tag)
return render(request, 'blog/tag_create.html', context={'form': bound_form})
Добавить валидацию
blog/forms.py
def clean_slug(self):
new_slug = self.cleaned_data['slug'].lower()
--/--/--
--/--/--
if Tag.objects.filter(slug__iexact=new_slug).count():
raise ValidationError('Slug must be unique. We have "{}" slug already'.format(new_slug))
return new_slug
Оптимизация
class TagForm(forms.ModelForm):
# title = forms.CharField(max_length=50)
# slug = forms.CharField(max_length=50)
#
# title.widget.attrs.update({'class': 'form-control'})
# slug.widget.attrs.update({'class': 'form-control'})
class Meta:
model = Tag
fields = ['title', 'slug']
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'slug': forms.TextInput(attrs={'class': 'form-control'})
}
--/--/--
--/--/--
# def save(self):
# new_tag = Tag.objects.create(
# title=self.cleaned_data['title'],
# slug=self.cleaned_data['slug']
# )
# return new_tag
```
Last updated