Last time, I learned how to implement unit tests in Django Tutorial (Blog App Creation) ④ --Unit Test Edition.
Originally, I would like to implement it in a test-driven development style that writes the expected test first because it is a big deal. In this tutorial, you'll learn what you can do with Django, so we'll implement it first and then write unit tests.
From now on, we will add the following functions this time in several parts.
We'll take the acronym for these features and call them "CRUD" here. (Strictly speaking, it may be different because you can already read with blog_list)
Now, let's add the ** article creation ** function, which can be said to be the base this time. Until now, articles were added with superuser privileges using the management site, but it is more convenient to be able to create articles within the app.
When adding data from the app, we use a mechanism called form. The form will be able to accept input data from the user, pass the data to the model through the view, and register it in the database.
First, create a file called forms.py under the blog app.
.
├── blog
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── forms.py #add to
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ └── __init__.py
│ ├── models.py
│ ├── tests
│ │ ├── __init__.py
│ │ ├── test_forms.py
│ │ ├── test_models.py
│ │ ├── test_urls.py
│ │ └── test_views.py
│ ├── urls.py
│ └── views.py
├── db.sqlite3
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── templates
└── blog
├── index.html
└── post_list.html
The contents of the created forms.py will look like this.
forms.py
from django import forms
from .models import Post
class PostCreateForm(forms.ModelForm): #Django's ModelForm has powerful Validation
class Meta:
model = Post #It connects with the Post model and creates a form according to the contents of the Post model.
fields = ('title', 'text') #Specify the column to enter
I think that you can understand to some extent because the explanation is also included. If you specify the model you want to input data to, form will prepare the corresponding input form.
In addition, although the column for entering data is specified as a field in the last row, You can also specify that all columns should be entered manually by defining ** fields ='all'**.
The class to be newly added to view is named ** PostCreateView in advance. Let's add the routing in urls.py as follows.
urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('post_list', views.PostListView.as_view(), name='post_list'),
path('post_create', views.PostCreateView.as_view(), name='post_create'), #add to
]
success_url specifies the page to redirect to if the database change is successful. Specify it in the form of "app name: reverse URL name", and as a result, you will be redirected to the'post_list' specified in urls.py.
You decided to add the class name PostCreateView earlier. I also created a class for the input form in form.
Next, create a class in views.py and again using the generic class view.
views.py
from django.views import generic
from django.urls import reverse_lazy
from .forms import PostCreateForm # forms.Import a class created with py
from .models import Post
class IndexView(generic.TemplateView):
template_name = 'blog/index.html'
class PostListView(generic.ListView):
model = Post
class PostCreateView(generic.CreateView): #add to
model = Post #Specify the model you want to create
form_class = PostCreateForm #Specify the created form class
success_url = reverse_lazy('blog:post_list') #Specify the redirect destination when the article is created successfully
That's all you need to do, thanks to Django's powerful class-based generic views. All you have to do is specify the model you want to create, the form class you created, and the redirect destination when the article was created successfully.
I haven't created the html for article creation (posting) yet, so let's create it under templates / blog. Name it post_form.html.
└── templates
└── blog
├── index.html
├── post_form.html #add to
└── post_list.html
post_create.html
<form action="" method="POST">
<table class="table">
<tr>
<th>title</th>
<td>{{ form.title }}</td>
</tr>
<tr>
<th>Text</th>
<td>{{ form.text }}</td>
</tr>
</table>
<button type="submit" class="btn btn-primary">Send</button>
{% csrf_token %}
</form>
Since the input field specified in fields of forms.py can be received by a variable called form, On the template side, it can be retrieved in the form of form.title and form.text.
It is also called CSRF (Cross-Site Request Forgery) to prevent attacks using input forms. Be sure to include it when displaying the input form in html.
If you start the server with the runserver command in this state, you will see an input form, although it looks terrible. (Often, I'll start with the basics of Django and then adjust the look.)
Let's enter a value and send it.
Pressing submit will redirect you to post_list. And you can see that the article I posted earlier has been added.
You have successfully added the article posting function.
Finally, let's implement a test for this feature.
Create the following test class in test_views.py.
test_views.py
...
class PostCreateTests(TestCase):
"""PostCreate view test class."""
def test_get(self):
"""Confirm that it is accessed by the GET method and status code 200 is returned."""
response = self.client.get(reverse('blog:post_create'))
self.assertEqual(response.status_code, 200)
def test_post_with_data(self):
"""Confirm that if you POST with appropriate data, you will be redirected successfully"""
data = {
'title': 'test_title',
'text': 'test_text',
}
response = self.client.post(reverse('blog:post_create'), data=data)
self.assertEqual(response.status_code, 302)
def test_post_null(self):
"""Confirm that POSTing with empty data returns only 200 without redirect"""
data = {}
response = self.client.post(reverse('blog:post_create'), data=data)
self.assertEqual(response.status_code, 200)
We are looking at the basic GET confirmation, the appropriate data input and redirect confirmation, and the response when empty data is input.
Finally, let's run the test.
You passed safely.
Next time, I will create the article details screen at once.
→ Next time Django Tutorial (Blog App Creation) ⑥ --Article Details / Editing / Deleting Functions
Recommended Posts