--- 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;">