Django开发个人博客项目-(10)通过markdown完成博客的展示和完成博客详情页面

欢迎访问我的博客:小羊驼的部落阁

博客详情页面

博客的详情页同样继承自base.html模板,可以将blog-detail.html拷贝到templates目录下。与归档、标签页面类似,按照之前的方法,分别编写视图函数与url代码:

view.py
class BlogDetailView(View):
    """
    博客详情页
    """
    def get(self, request, blog_id):
        blog = Blog.objects.get(id=blog_id)
        return render(request, 'blog-detail.html', {
            'blog': blog,

        })
urls.py

我们这里采用博客的id进行url传参

url(r'^blog/(?P<blog_id>\d+)$', BlogDetailView.as_view(), name='blog_id'),

同样,要在之前的归档与分类详情页面添加上博客的url链接:

href="{% url 'blog_id' blog.id %}"

然后在模板中将博客的标题,创建时间,分类,内容,以及标签写上就行了。这里仅对标签进行说明下,标签与博客是多对多的关系,因此可以按照如下方式获得博客的所有标签:

{% for blog_tag in blog.tag.all %}
    <a href="{% url 'tag_name' blog_tag.name %}" rel="tag"># {{ blog_tag.name }}</a>
{% endfor %}

实现博客的上一篇与下一篇功能

为了实现这个功能,我们需要在视图函数中获取该篇博客的上一篇博客以及下一篇博客。为了实现这个功能,我们需要考虑到以下2种情况:

博客的id号有可能是不连续的,当我们删除一篇博客时,连带着该id号一块删除了,如果通过blog_id - 1和blog_id+1来获取博客的上一篇与下一篇,则有可能会出错。
如果是第一篇博客,它是没有上一篇的;同样,最后一篇博客也是没有下一篇的
因此,我们可以使用状态码has_prev和has_next来判断博客是否有上一篇和下一篇,并通过对id进行循环来判断id号码的连续性,实现代码如下:

view.py
#实现博客上一篇与下一篇功能

has_prev = False
has_next = False
id_prev = id_next = int(blog_id)
blog_id_max = Blog.objects.all().order_by('-id').first()
id_max = blog_id_max.id
while not has_prev and id_prev >= 1:
    blog_prev = Blog.objects.filter(id=id_prev - 1).first()
    if not blog_prev:
        id_prev -= 1
    else:
        has_prev = True
while not has_next and id_next <= id_max:
    blog_next = Blog.objects.filter(id=id_next + 1).first()
    if not blog_next:
        id_next += 1
    else:
        has_next = True

#将状态码与上下博客传递给前端页面
'blog_prev': blog_prev,
'blog_next': blog_next,
'has_prev': has_prev,
'has_next': has_next,

blog-detail.html

#判断是否有上一篇
<div class="post-nav">
        <div class="post-nav-next post-nav-item">
            {% if has_prev %}
                <a href="{% url 'blog_id' blog_prev.id %}" rel="prev"
                   title="{{ blog_prev.title }}">
                    <i class="fa fa-chevron-left"></i> {{ blog_prev.title }}
                </a>
            {% endif %}
        </div>
        <span class="post-nav-divider"></span>
        <div class="post-nav-prev post-nav-item">
            {% if has_next %}
                <a href="{% url 'blog_id' blog_next.id %}" rel="next"
                   title="{{ blog_next.title }}">
                    {{ blog_next.title }} <i class="fa fa-chevron-right"></i>
                </a>
            {% endif %}
        </div>
    </div>

如此,即可实现博客的上一篇与下一篇功能。

markdown

什么是markdown语法,我们的CSDN、简书、博客园等都是用的markdown语法。它规则很简单,可以参考如下资料:

Markdown——入门指南

安装markdown

进入虚拟环境:

pip install markdown
pip install django-mdeditor

在INSTALLED_APPS中注册

...
'mdeditor',
...

将路径添加到url中

from django.urls import include, re_path
re_path(r'mdeditor/', include('mdeditor.urls')),

在models.py中将文本区域替换:

from mdeditor.fields import MDTextField #必须导入
content = MDTextField()    #注意为MDTextField()

然后在view视图中:

import markdown
class BlogDetailView(View):
    """
    博客详情页
    """
    def get(self, request, blog_id):
        blog = Blog.objects.get(id=blog_id)

        # 将博客内容用markdown显示出来
        blog.content = markdown.markdown(blog.content, extensions=[
                                     'markdown.extensions.extra',
                                     'markdown.extensions.codehilite',
                                     'markdown.extensions.toc',
                                  ])

        return render(request, 'blog_detail.html', {
            'blog': blog,
         
        })

渲染 Markdown

将 Markdown 格式的文本渲染成 HTML 文本非常简单,只需调用这个库的 markdown 方法即可。我们书写的博客文章内容存在 Blog的 content属性里,回到我们的详情页视图函数,对Blog 的 content的值做一下渲染,把 Markdown 文本转为 HTML 文本再传递给模板:

这样我们在模板中展示 {{ blog.content }} 的时候,就不再是原始的 Markdown 文本了,而是渲染过后的 HTML 文本。

blog-detail.html
{{ blog.content|safe }}

Django 出于安全方面的考虑,任何的 HTML 代码在 Django 的模板中都会被转义(即显示原始的 HTML 代码,而不是经浏览器渲染后的格式)。为了解除转义,只需在模板标签使用 safe 过滤器即可,告诉 Django,这段文本是安全的,你什么也不用做。

这样,再次刷新页面,就可以看到带有样式的博客页面了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容