---
tags: Python Web
source: https://python-scripts.com/django-forms
---
# Тема 5. Формы для блога
https://github.com/roman-yatsenko/django-topics/tree/main/django-forms
## Форма для создания записи на блоге (CreateView)
### `templates\base.html`
```htmlmixed=9
<header>
<div class="nav-left">
<h1><a href="{% url 'home' %}">Django blog</a></h1>
</div>
<div class="nav-right">
<a href="{% url 'post_new' %}">+ New Blog Post</a>
</div>
</header>
```
### `static\css\base.css`
```css=6
header {
border-bottom: 1px solid #999;
margin-bottom: 2rem;
display: flex;
}
.nav-left {
margin-right: auto;
}
.nav-right {
display: flex;
padding-top: 2rem;
}
```
### `blog\urls.py`
```python=
from django.urls import path
from .views import BlogListView, BlogDetailView, BlogCreateView # new
urlpatterns = [
path('post/new/', BlogCreateView.as_view(), name='post_new'), # new
path('post/<int:pk>/', BlogDetailView.as_view(), name='post_detail'),
path('', BlogListView.as_view(), name='home'),
]
```
### `blog\views.py`
```python=
from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView # new
```
```python=17
class BlogCreateView(CreateView): # new
model = Post
template_name = 'post_new.html'
fields = ['title', 'author', 'body']
```
### `templates\post_new.html`
```shell
touch templates/post_new.html
```
```htmlmixed=
{% extends 'base.html' %}
{% block content %}
<h1>New post</h1>
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>
{% endblock content %}
```
```shell
python manage.py runserver
```
### `blog\models.py`
```python=
from django.db import models
from django.urls import reverse # new
```
```python=15
def get_absolute_url(self): # new Post method
return reverse('post_detail', args=[str(self.id)])
```
## Форма для обновления данных (UpdateView)
### `templates\post_detail.html`
```htmlmixed=9
<a href='{% url 'post_edit' post.pk %}'>+ Edit Blog Post</a>
{% endblock content %}
```
```shell
touch templates/post_edit.html
```
### `templates\post_edit.html`
```htmlmixed=
{% extends 'base.html' %}
{% block content %}
<h1>Edit post</h1>
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Update" />
</form>
{% endblock content %}
```
### `blog\views.py`
```python=
from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView # new
```
```python=22
class BlogUpdateView(UpdateView): # new
model = Post
template_name = 'post_edit.html'
fields = ['title', 'body']
```
### `blog\urls.py`
```python=
from django.urls import path
from .views import (
BlogListView,
BlogDetailView,
BlogCreateView,
BlogUpdateView, # new
)
urlpatterns = [
path('post/<int:pk>/edit/', BlogUpdateView.as_view(), name='post_edit'), # new
path('post/new/', BlogCreateView.as_view(), name='post_new'),
path('post/<int:pk>/', BlogDetailView.as_view(), name='post_detail'),
path('', BlogListView.as_view(), name='home'),
]
```
```shell
python manage.py runserver
```
## Страница удаления записи (DeleteView)
### `templates\post_detail.html`
```htmlmixed=9
<p><a href="{% url 'post_edit' post.pk %}">+ Edit Blog Post</a></p>
<p><a href="{% url 'post_delete' post.pk %}">+ Delete Blog Post</a></p>
{% endblock content %}
```
```shell
touch templates/post_delete.html
```
### `templates\post_delete.html`
```htmlmixed=
{% extends 'base.html' %}
{% block content %}
<h1>Delete post</h1>
<form action="" method="post">{% csrf_token %}
<p>Are you sure you want to delete "{{ post.title }}"?</p>
<input type="submit" value="Confirm" />
</form>
{% endblock content %}
```
### `blog\views.py`
```python=
from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView # new
from django.urls import reverse_lazy # new
```
```python=30
class BlogDeleteView(DeleteView): # new
model = Post
template_name = 'post_delete.html'
success_url = reverse_lazy('home')
```
### `blog\urls.py`
```python=3
from .views import (
BlogListView,
BlogUpdateView,
BlogDetailView,
BlogCreateView,
BlogDeleteView, # new
)
urlpatterns = [
path('post/<int:pk>/delete/', # new
BlogDeleteView.as_view(), name='post_delete'),
path('post/new/', BlogCreateView.as_view(), name='post_new'),
path('post/<int:pk>/', BlogDetailView.as_view(), name='post_detail'),
path('post/<int:pk>/edit/',
BlogUpdateView.as_view(), name='post_edit'),
path('', BlogListView.as_view(), name='home'),
]
```
```shell
python manage.py runserver
```
## Тестируем добавление, обновление и удаление записей
### `blog\tests.py`
```python=46
def test_get_absolute_url(self): # new
self.assertEqual(self.post.get_absolute_url(), '/post/1/')
def test_post_create_view(self): # new
response = self.client.post(reverse('post_new'), {
'title': 'New title',
'body': 'New text',
'author': self.user,
})
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'New title')
self.assertContains(response, 'New text')
def test_post_update_view(self): # new
response = self.client.post(reverse('post_edit', args='1'), {
'title': 'Updated title',
'body': 'Updated text',
})
self.assertEqual(response.status_code, 302)
def test_post_delete_view(self): # new
response = self.client.post(
reverse('post_delete', args='1'))
self.assertEqual(response.status_code, 302)
```
```shell
python manage.py test
```
---
(c) Яценко Р.Н., 2018-2020
[Учебный центр компьютерных технологий "Кит"](http://kit.kh.ua/)
<img src="https://i.imgur.com/Kh901c1.png" style="width: 150px; position: fixed; top: 100px; right: 10px; border: 0; box-shadow: none;">