资讯专栏INFORMATION COLUMN

python实战----博客系统(完善)

animabear / 3420人阅读

摘要:上一篇博客系统的博客还没有实现评论,按标签搜索按日期搜索按分类搜索的功能,这篇博客主要是对以上功能的增加。博客首页修改主页的文件有关分页显示的部分上一页上一页第页共页下一页下一页

上一篇‘博客系统’的博客还没有实现评论,按标签搜索、按日期搜索、按分类搜索的功能,这篇博客主要是对以上功能的增加。

增添评论

第一步:新建app:comment,在主setting.py中添加新app,修改主urls.py文件

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r"^admin/", admin.site.urls),
    url(r"",include("blog.urls")),
    url(r"",include("comments.urls")),

]

第二步:编写评论的数据库表单

from django.contrib.auth.models import User
from django.db import models

# Create your models here.
from blog.models import Post


class Comment(models.Model):
    user =models.ForeignKey(User,verbose_name="用户")
    email = models.EmailField(verbose_name="电子邮箱")
    text = models.TextField(max_length=255,verbose_name="评论正文")
    # auto_now_add=True 自动create_time为最新一次更改评论信息的时间
    create_time = models.DateTimeField(auto_now_add=True,verbose_name="创建时间")
    post = models.ForeignKey(Post)
    class Meta:
        verbose_name = "评论"
        verbose_name_plural = "评论"

    def __str__(self):
        return  self.text[:4]

第三步:编写评论的路由comment.urls.py和comment.views.py

# comment.views.py
from django.shortcuts import render, get_object_or_404,redirect

# Create your views here.
from blog.models import Post
from comments.forms import CommentForm


def post_comment(request, id):
    # 1. 获取用户选择的博客
    post = get_object_or_404(Post, id=id)
    # 2. 如果用户提交评论
    if request.method == "POST":
        print(request.POST)
        form = CommentForm(request.POST)
        # 2.1 判断表单是否合法
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.save()
        # 2.2 如果不合法,则提交错误信息
        else:
            return render(request, "blog/detail.html",
                          context={
                              "errors": form.errors
                          })
    # 3. 如果不是POST请求,访问用户详情页
    return redirect(post.get_url())
# comment.urls
from django.conf.urls import url, include
from django.contrib import admin

from comments import views

app_name = "comment"
urlpatterns = [
    url(r"^comment/blog/(?Pd+)/$",views.post_comment,name="post_comment"),
]

第四步:编写评论表单

# 同步与数据库评论的形式
from comments.models import Comment


class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ["user","email","text"]

第五步:修改HTML文件中关于评论的部分


发表评论

{% csrf_token %}
{{ form.user }}
{{ form.email }}
{{ form.text }}

评论列表,共 {{ comments.count }} 条评论

    {% for comment in comments %}
  • {{ comment.user }}
    {{ comment.text }}
  • {% endfor %}


自定义标签

实现按标签搜索、按日期搜索、按分类搜索的功能

第一步:自定义标签

准备(必需)工作:

在某个app下创建一个名为templatetags(必需,且包名不可变)的包。假设我们在名为blog的app下创建了一个templatetags的包,并在该包下创建了一个名为blog_tags的文件.
 确保settings文件中的INSTALLD_APPS内必须含有该app
 修改setting.py有关时间显示的部分

# TIME_ZONE = "UTC"
TIME_ZONE = "Asia/Shanghai"

USE_I18N = True

USE_L10N = True

#如果setting中配置USE_TZ=True则输出的是UTC时间(naive time),
# 如果setting中配置USE_TZ=False,则该输出时间与datetime.datetime.now()完全相同
# USE_TZ = True
USE_TZ = False
2. 接下来在blog_tags文件中写入如下几行
from django import template

register = template.Library()
 3. 在模板中使用{% load %} 标签装载自定义标签或者装饰器
from django import template
from django.db.models import Count

from blog.models import Post, Category, Tag

register = template.Library()

@register.simple_tag
def get_recent_posts(num=3):
    return Post.objects.all().order_by("-create_time")[:num]


@register.simple_tag
def archives():

    return Post.objects.dates(field_name="create_time",
                              kind="month",
                              order="DESC")

@register.simple_tag
def get_category():
    return Category.objects.annotate(num_posts=Count("post")).filter(num_posts__gt=0)


@register.simple_tag
def get_tags():
    # return Tag.objects.all()
    return Tag.objects.annotate(num_posts = Count("post"))

第二步: 编写标签查找的路由和视图函数

路由

#blog.urls.py
from django.conf.urls import url

from django.contrib import admin

from blog import views

app_name = "blog"
urlpatterns = [
    url(r"^$", views.index, name="index"),
    url(r"blog/(?Pd+)/$", views.detail, name="detail"),
    url(r"^archive/(?Pd{4})/(?Pd{1,2})/", views.archive, name="archive"),
    url(r"^category/(?Pd+)/", views.category, name="category"),
    url(r"^tag/(?Pd+)/", views.tag, name="tag"),
    url(r"^search", views.search, name="search")
]

视图函数

from django.db.models import Q
from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404

# Create your views here.
from markdown import markdown

from blog.models import Post, Tag
from comments.forms import CommentForm


def index(request):
    # return HttpResponse("ok index!")
    posts = Post.objects.all()
    return render(request,"blog/index.html",context={
        "posts":posts
    })
def detail(request,id):
    # return HttpResponse("ok,%s detail" %(id))
    post = Post.objects.get(id=id)
    post.add_views()
    form = CommentForm()
    comments = post.comment_set.all()
    post.body = markdown(post.body,
                         extensions=["markdown.extensions.extra",
                                     "markdown.extensions.codehilite",
                                     "markdown.extensions.toc", ],
                         output_format="html")
    return render(request,"blog/detail.html",context={
        "post":post,
        "comments":comments,
        "form":form,
    })
def archive(request,year,month):
    posts = Post.objects.filter(
        create_time__year=year,
        create_time__month=month
    ).order_by("-create_time")

    return  render(request,"blog/index.html",context={
        "posts":posts
    })


def category(request,id):
    posts = Post.objects.filter(category_id=id)
    return render(request,"blog/index.html",
                  context={
                      "posts":posts

                  })


def tag(request,id):
    tag = get_object_or_404(Tag,id=id)
    posts = Post.objects.filter(tags=tag).order_by("-create_time")
    return render(
        request, "blog/index.html",
        context={
            "posts": posts

        }


    )


def search(request):
    query = request.GET.get("query",None)
    posts = Post.objects.filter(
        Q(title__icontains=query) |
        Q(body__icontains=query)
    )

    if not posts:
        return render(request,"blog/index.html",
                      context={
                          "posts":posts,
                          "message":"没有找到相关信息"
                      }
                      )
    else:
        return render(request, "blog/index.html",
                      context={
                          "posts": posts

                      }
                      )

第三步:修改Html文件,仅截取部分代码

这里在博客详情页需要显示的是博客的结构(目录),添加显示目录的代码
修改视图函数

def detail(request,id):
    # return HttpResponse("ok,%s detail" %(id))
    post = Post.objects.get(id=id)
    post.add_views()
    form = CommentForm()
    comments = post.comment_set.all()
    # post.body = markdown(post.body,
    #                      extensions=["markdown.extensions.extra",
    #                                  "markdown.extensions.codehilite",
    #                                  "markdown.extensions.toc", ],
    #                      output_format="html")
    md = Markdown(
        extensions=["markdown.extensions.extra",
                    "markdown.extensions.codehilite",
                    "markdown.extensions.toc", ],
        output_format="html"
    )
    # Convert markdown to serialized XHTML or HTML.
    post.body = md.convert(post.body)
    post.toc = md.toc
    return render(request,"blog/detail.html",context={
        "post":post,
        "comments":comments,
        "form":form,

    })

右侧导航栏

{#     基模板       #}

   

详情页添加博客目录

{# blog/detail.html #}
{% block toc %}
    

文章目录

{{ post.toc | safe }}
{% endblock %}
按类别查找

按标签查找

按时间查找

显示博客目录

分页

Django提供了一个新的类来帮助你管理分页数据,这个类存放在django/core/paginator.py.它可以接收列表、元组或其它可迭代的对象。

def index(request):
    all_posts = Post.objects.count()
    if all_posts % PER_PAGE != 0:
        page_nums = all_posts // PER_PAGE + 1
    else:
        page_nums = all_posts // PER_PAGE
    paginator = Paginator(Post.objects.all(),PER_PAGE)
    if  request.GET.get("page"):
        page = request.GET.get("page")
    else:
        page = 1
    try:
        posts = paginator.page(page)
    except (PageNotAnInteger,EmptyPage):
        posts = paginator.page(1)

        posts.has_previous()
        posts.has_next()
        posts.previous_page_number()
        posts.next_page_number()


    return render(request, "blog/index.html",
                  context={
        "title":"博客首页",
        "posts":posts,
        "pages_num":page_nums,
    })
修改主页的html文件有关分页显示的部分
  
{% if posts.has_previous %} 上一页 {% else %} 上一页 {% endif %} 第 {{ posts.number }} 页 / 共 {{ pages_num }} 页 {% if posts.has_next %} 下一页 {% else %} 下一页

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42646.html

相关文章

  • Python - 收藏集 - 掘金

    摘要:首发于我的博客线程池进程池网络编程之同步异步阻塞非阻塞后端掘金本文为作者原创,转载请先与作者联系。在了解的数据结构时,容器可迭代对象迭代器使用进行并发编程篇二掘金我们今天继续深入学习。 Python 算法实战系列之栈 - 后端 - 掘金原文出处: 安生    栈(stack)又称之为堆栈是一个特殊的有序表,其插入和删除操作都在栈顶进行操作,并且按照先进后出,后进先出的规则进行运作。 如...

    546669204 评论0 收藏0
  • Django 学习小组:博客开发实战第三周教程——文章列表分页和代码语法高亮

    摘要:本教程内容已过时,更新版教程请访问博客开发入门教程。当分页较多时,总是显示当前页及其前几页和后几页的页码教程中使用的是两页,其他页码用省略号代替。 本教程内容已过时,更新版教程请访问: django 博客开发入门教程。 摘要:前两期教程我们实现了博客的 Model 部分,以及 Blog 的首页视图 IndexView,详情页面 DetailView,以及分类页面 CategoryVi...

    Luosunce 评论0 收藏0

发表评论

0条评论

animabear

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<