|
3 | 3 | import markdown
|
4 | 4 | from django.shortcuts import get_object_or_404, render
|
5 | 5 | from django.utils.text import slugify
|
| 6 | +from django.views.generic import DetailView, ListView |
6 | 7 | from markdown.extensions.toc import TocExtension
|
7 | 8 |
|
8 | 9 | from .models import Category, Post, Tag
|
9 | 10 |
|
10 | 11 |
|
11 |
| -def index(request): |
12 |
| - post_list = Post.objects.all() |
13 |
| - return render(request, 'blog/index.html', context={'post_list': post_list}) |
| 12 | +class IndexView(ListView): |
| 13 | + model = Post |
| 14 | + template_name = 'blog/index.html' |
| 15 | + context_object_name = 'post_list' |
14 | 16 |
|
15 | 17 |
|
16 |
| -def archive(request, year, month): |
17 |
| - post_list = Post.objects.filter(created_time__year=year, |
18 |
| - created_time__month=month |
19 |
| - ) |
20 |
| - return render(request, 'blog/index.html', context={'post_list': post_list}) |
| 18 | +class CategoryView(IndexView): |
21 | 19 |
|
| 20 | + def get_queryset(self): |
| 21 | + cate = get_object_or_404(Category, pk=self.kwargs.get('pk')) |
| 22 | + return super().get_queryset().filter(category=cate) |
22 | 23 |
|
23 |
| -def category(request, pk): |
24 |
| - # 记得在开始部分导入 Category 类 |
25 |
| - cate = get_object_or_404(Category, pk=pk) |
26 |
| - post_list = Post.objects.filter(category=cate) |
27 |
| - return render(request, 'blog/index.html', context={'post_list': post_list}) |
28 | 24 |
|
| 25 | +class ArchiveView(IndexView): |
| 26 | + def get_queryset(self): |
| 27 | + year = self.kwargs.get('year') |
| 28 | + month = self.kwargs.get('month') |
| 29 | + return super().get_queryset().filter(created_time__year=year, |
| 30 | + created_time__month=month) |
29 | 31 |
|
30 |
| -def tag(request, pk): |
31 |
| - # 记得在开始部分导入 Tag 类 |
32 |
| - t = get_object_or_404(Tag, pk=pk) |
33 |
| - post_list = Post.objects.filter(tags=t) |
34 |
| - return render(request, 'blog/index.html', context={'post_list': post_list}) |
35 | 32 |
|
| 33 | +class TagView(IndexView): |
| 34 | + def get_queryset(self): |
| 35 | + t = get_object_or_404(Tag, pk=self.kwargs.get('pk')) |
| 36 | + return super().get_queryset().filter(tags=t) |
36 | 37 |
|
37 |
| -def detail(request, pk): |
38 |
| - post = get_object_or_404(Post, pk=pk) |
39 | 38 |
|
40 |
| - # 阅读量 +1 |
41 |
| - post.increase_views() |
| 39 | +# 记得在顶部导入 DetailView |
| 40 | +class PostDetailView(DetailView): |
| 41 | + # 这些属性的含义和 ListView 是一样的 |
| 42 | + model = Post |
| 43 | + template_name = 'blog/detail.html' |
| 44 | + context_object_name = 'post' |
42 | 45 |
|
43 |
| - md = markdown.Markdown(extensions=[ |
44 |
| - 'markdown.extensions.extra', |
45 |
| - 'markdown.extensions.codehilite', |
46 |
| - # 记得在顶部引入 TocExtension 和 slugify |
47 |
| - TocExtension(slugify=slugify), |
48 |
| - ]) |
49 |
| - post.body = md.convert(post.body) |
| 46 | + def get(self, request, *args, **kwargs): |
| 47 | + # 覆写 get 方法的目的是因为每当文章被访问一次,就得将文章阅读量 +1 |
| 48 | + # get 方法返回的是一个 HttpResponse 实例 |
| 49 | + # 之所以需要先调用父类的 get 方法,是因为只有当 get 方法被调用后, |
| 50 | + # 才有 self.object 属性,其值为 Post 模型实例,即被访问的文章 post |
| 51 | + response = super().get(request, *args, **kwargs) |
50 | 52 |
|
51 |
| - m = re.search(r'<div class="toc">\s*<ul>(.*)</ul>\s*</div>', md.toc, re.S) |
52 |
| - post.toc = m.group(1) if m is not None else '' |
| 53 | + # 将文章阅读量 +1 |
| 54 | + # 注意 self.object 的值就是被访问的文章 post |
| 55 | + self.object.increase_views() |
53 | 56 |
|
54 |
| - return render(request, 'blog/detail.html', context={'post': post}) |
| 57 | + # 视图必须返回一个 HttpResponse 对象 |
| 58 | + return response |
| 59 | + |
| 60 | + def get_object(self, queryset=None): |
| 61 | + # 覆写 get_object 方法的目的是因为需要对 post 的 body 值进行渲染 |
| 62 | + post = super().get_object(queryset=None) |
| 63 | + md = markdown.Markdown(extensions=[ |
| 64 | + 'markdown.extensions.extra', |
| 65 | + 'markdown.extensions.codehilite', |
| 66 | + # 记得在顶部引入 TocExtension 和 slugify |
| 67 | + TocExtension(slugify=slugify), |
| 68 | + ]) |
| 69 | + post.body = md.convert(post.body) |
| 70 | + |
| 71 | + m = re.search(r'<div class="toc">\s*<ul>(.*)</ul>\s*</div>', md.toc, re.S) |
| 72 | + post.toc = m.group(1) if m is not None else '' |
| 73 | + |
| 74 | + return post |
0 commit comments