Django Blog - 02. 详情页及测试

Views

blog/views.py文件中增加新的视图类BlogDetailView

1
2
3
4
5
6
7
8
9
10
from django.views.generic import ListView, DetailView
from . models import Post

class BlogListView(ListView):
model = Post
template_name = 'home.html'

class BlogDetailView(DetailView):
model = Post
template_name = 'post_detail.html'

默认情况下,DetailView 会提供一个上下文对象object或小写的模型(model)名字post用在模板文件中
DetailView 需要一个主键或slug作为标识符。后面详述…

Templates

新建templates/post_detail.html文件,内容如下:

1
2
3
4
5
6
7
8
{% extends 'base.html' %}

{% block content %}
<div class="post-entry">
<h2>{{ post.title }}</h2>
<p>{{ post.body }}</p>
</div>
{% endblock content %}

URLs

修改blog/urls.py文件,代码如下:

1
2
3
4
5
6
7
8
from django.urls import path

from . import views

urlpatterns = [
path('', views.BlogListView.as_view(), name='home'),
path('post/<int:pk>/', views.BlogDetailView.as_view(), name='post_detail'),
]

再次运行程序,访问页面http://127.0.0.1:8000/post/1/ ,显示如下:

upload successful

更新templates/home.html文件,添加页面链接,代码如下:

1
2
3
4
5
6
7
8
9
10
{% extends 'base.html' %}

{% block content %}
{% for post in object_list %}
<div class="post-entry">
<h2><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</a></h2>
<p>{{ post.body }}</p>
</div>
{% endfor %}
{% endblock content %}

Tests

增加针对模型和视图的测试代码,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from django.test import TestCase, Client
from django.contrib.auth import get_user_model
from django.urls import reverse

from .models import Post

class BlogTests(TestCase):
def setUp(self):
self.user = get_user_model().objects.create_user(
username = 'testuser',
email = 'test@email.com',
password = 'secret'
)

self.post = Post.objects.create(
title = 'A good title',
body = 'Nice body content',
author = self.user,
)

def test_string_representation(self):
post = Post(title='A sample title')
self.assertEqual(str(post), post.title)

def test_post_content(self):
self.assertEqual(f'{self.post.title}', 'A good title')
self.assertEqual(f'{self.post.author}', 'testuser')
self.assertEqual(f'{self.post.body}', 'Nice body content')

def test_post_list_view(self):
response = self.client.get(reverse('home'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Nice body content')
self.assertTemplateUsed(response, 'home.html')

def test_post_detail_view(self):
response = self.client.get('/post/1/')
no_response = self.client.get('/post/1000/')
self.assertEqual(response.status_code, 200)
self.assertEqual(no_response.status_code, 404)
self.assertContains(response, 'A good title')
self.assertTemplateUsed(response, 'post_detail.html')

执行如下命令,运行测试用例:

1
python manage.py test