diff --git a/README.md b/README.md index ac458c3..651e56f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,24 @@ +**第二版已发布!第二版已发布!第二版已发布!** + +Django博客教程第二版全面升级,带来以下新特性,帮助初学者更好地学习 django: + +1. 基于最新版 django 2.2 +2. Pipenv 无痛管理虚拟环境和依赖 +3. 更加简单无痛苦的部署流程,几条命令快速上线,一键脚本无痛更新 +4. 开启 HTTPS 新时代 +5. Elasticsearch 全文搜索 + +**强烈不再建议学习旧版**,第二版教程戳下面直达: + +- [HelloDjango-blog-tutorial GitHub 仓库](https://github.com/HelloGitHub-Team/HelloDjango-blog-tutorial) +- [Django博客教程(第二版)](https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/) + +> PS: +> +> Django 全栈计划已启动,戳 [这里](https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/) 了解详情,感兴趣的童鞋请持续关注我的博客:[追梦人物的博客](https://www.zmrenwu.com/)。 + +-------- + 免费、中文、零基础,完整的项目,基于最新版 Django 1.10 和 Python 3.5。带你从零开始一步步开发属于自己的博客网站,帮助你以最快的速度掌握 Django 开发的技巧。 ## 资源列表 diff --git a/blog/views.py b/blog/views.py index c6d14e5..71ddda9 100644 --- a/blog/views.py +++ b/blog/views.py @@ -261,11 +261,8 @@ def archives(request, year, month): return render(request, 'blog/index.html', context={'post_list': post_list}) -class ArchivesView(ListView): - model = Post - template_name = 'blog/index.html' - context_object_name = 'post_list' - +# 归档页面,继承IndexView,可以拥有分页功能,减少代码量 +class ArchivesView(IndexView): def get_queryset(self): year = self.kwargs.get('year') month = self.kwargs.get('month') @@ -280,21 +277,15 @@ def category(request, pk): return render(request, 'blog/index.html', context={'post_list': post_list}) -class CategoryView(ListView): - model = Post - template_name = 'blog/index.html' - context_object_name = 'post_list' - +# 分类页面,继承IndexView +class CategoryView(IndexView): def get_queryset(self): cate = get_object_or_404(Category, pk=self.kwargs.get('pk')) return super(CategoryView, self).get_queryset().filter(category=cate) -class TagView(ListView): - model = Post - template_name = 'blog/index.html' - context_object_name = 'post_list' - +# 标签页面,继承自IndexView +class TagView(IndexView): def get_queryset(self): tag = get_object_or_404(Tag, pk=self.kwargs.get('pk')) return super(TagView, self).get_queryset().filter(tags=tag) diff --git a/comments/views.py b/comments/views.py index ae1824e..5e45578 100644 --- a/comments/views.py +++ b/comments/views.py @@ -1,54 +1,51 @@ from django.shortcuts import render, get_object_or_404, redirect +from django.views.decorators.http import require_POST from blog.models import Post from .models import Comment from .forms import CommentForm +@require_POST def post_comment(request, post_pk): # 先获取被评论的文章,因为后面需要把评论和被评论的文章关联起来。 # 这里我们使用了 Django 提供的一个快捷函数 get_object_or_404, # 这个函数的作用是当获取的文章(Post)存在时,则获取;否则返回 404 页面给用户。 post = get_object_or_404(Post, pk=post_pk) - # HTTP 请求有 get 和 post 两种,一般用户通过表单提交数据都是通过 post 请求, - # 因此只有当用户的请求为 post 时才需要处理表单数据。 - if request.method == 'POST': - # 用户提交的数据存在 request.POST 中,这是一个类字典对象。 - # 我们利用这些数据构造了 CommentForm 的实例,这样 Django 的表单就生成了。 - form = CommentForm(request.POST) - - # 当调用 form.is_valid() 方法时,Django 自动帮我们检查表单的数据是否符合格式要求。 - if form.is_valid(): - # 检查到数据是合法的,调用表单的 save 方法保存数据到数据库, - # commit=False 的作用是仅仅利用表单的数据生成 Comment 模型类的实例,但还不保存评论数据到数据库。 - comment = form.save(commit=False) - - # 将评论和被评论的文章关联起来。 - comment.post = post - - # 最终将评论数据保存进数据库,调用模型实例的 save 方法 - comment.save() - - # 重定向到 post 的详情页,实际上当 redirect 函数接收一个模型的实例时,它会调用这个模型实例的 get_absolute_url 方法, - # 然后重定向到 get_absolute_url 方法返回的 URL。 - return redirect(post) - - else: - # 检查到数据不合法,重新渲染详情页,并且渲染表单的错误。 - # 因此我们传了三个模板变量给 detail.html, - # 一个是文章(Post),一个是评论列表,一个是表单 form - # 注意这里我们用到了 post.comment_set.all() 方法, - # 这个用法有点类似于 Post.objects.all() - # 其作用是获取这篇 post 下的的全部评论, - # 因为 Post 和 Comment 是 ForeignKey 关联的, - # 因此使用 post.comment_set.all() 反向查询全部评论。 - # 具体请看下面的讲解。 - comment_list = post.comment_set.all() - context = {'post': post, - 'form': form, - 'comment_list': comment_list - } - return render(request, 'blog/detail.html', context=context) - # 不是 post 请求,说明用户没有提交数据,重定向到文章详情页。 - return redirect(post) + # 用户提交的数据存在 request.POST 中,这是一个类字典对象。 + # 我们利用这些数据构造了 CommentForm 的实例,这样 Django 的表单就生成了。 + form = CommentForm(request.POST) + + # 当调用 form.is_valid() 方法时,Django 自动帮我们检查表单的数据是否符合格式要求。 + if form.is_valid(): + # 检查到数据是合法的,调用表单的 save 方法保存数据到数据库, + # commit=False 的作用是仅仅利用表单的数据生成 Comment 模型类的实例,但还不保存评论数据到数据库。 + comment = form.save(commit=False) + + # 将评论和被评论的文章关联起来。 + comment.post = post + + # 最终将评论数据保存进数据库,调用模型实例的 save 方法 + comment.save() + + # 重定向到 post 的详情页,实际上当 redirect 函数接收一个模型的实例时,它会调用这个模型实例的 get_absolute_url 方法, + # 然后重定向到 get_absolute_url 方法返回的 URL。 + return redirect(post) + + else: + # 检查到数据不合法,重新渲染详情页,并且渲染表单的错误。 + # 因此我们传了三个模板变量给 detail.html, + # 一个是文章(Post),一个是评论列表,一个是表单 form + # 注意这里我们用到了 post.comment_set.all() 方法, + # 这个用法有点类似于 Post.objects.all() + # 其作用是获取这篇 post 下的的全部评论, + # 因为 Post 和 Comment 是 ForeignKey 关联的, + # 因此使用 post.comment_set.all() 反向查询全部评论。 + # 具体请看下面的讲解。 + comment_list = post.comment_set.all() + context = {'post': post, + 'form': form, + 'comment_list': comment_list + } + return render(request, 'blog/detail.html', context=context) diff --git a/templates/blog/index.html b/templates/blog/index.html index e53bede..4d82b11 100644 --- a/templates/blog/index.html +++ b/templates/blog/index.html @@ -54,33 +54,46 @@