Django筆記10-文章詳情頁(yè)(2)

文章詳情頁(yè)

使用 markdown 語(yǔ)法發(fā)布文章以及評(píng)論功能

Markdown 編輯器

?Markdown 的語(yǔ)法簡(jiǎn)潔明了、學(xué)習(xí)容易,而且功能比純文本更強(qiáng),因此有很多人用它寫(xiě)博客。而作為一個(gè)博客網(wǎng)站,支持 markdown 也是必然的。

安裝 markdown

# 在虛擬環(huán)境中執(zhí)行
$ pip install markdown

修改視圖函數(shù)

?在視圖中將文章內(nèi)容的 markdown 語(yǔ)法 渲染成 HTML 文本

from markdown import markdown
...

def article(request, slug):
    context = {}
    article = Article.objects.get(title=slug)
    # 將內(nèi)容文本渲染成 HTML 文本
    article.body = markdown(
        article.body,
        extensions = [
            'markdown.extensions.extra',
            'markdown.extensions.codehilite',
            'markdown.extensions.toc',
        ] 
    )
    context['article'] = article
    if request.user.is_authenticated:
        context['username']= request.user.username
    return render(request, 'blog/article.html', context=context)

?這里要注意,在模板文件中 {{ article.body }} 標(biāo)簽要修改成 {{ article.body | safe }} ,因?yàn)?django 處于安全考慮會(huì)將任何 HTML 代碼進(jìn)行轉(zhuǎn)義。

語(yǔ)法高亮

?當(dāng)在文章中添加了一些代碼實(shí)例時(shí),根據(jù)所屬語(yǔ)言渲染,達(dá)到高亮的效果

# 注意在虛擬環(huán)境中安裝
$ pip install Pygments

安裝完成之后,執(zhí)行一下命令生成一個(gè) css 文件

$ pygmentize -S default -f html -a .codehilite > code.css

?把生成的 code.css 文件放入靜態(tài)文件中,再在模板文件中引用

<!-- templates/blog/article.html -->
...
<link rel="stylesheet" type="text/css" href="/static/blog/css/highlights/code.css">
...

評(píng)論功能

?評(píng)論功能相對(duì)獨(dú)立,所以新建一個(gè)應(yīng)用來(lái)完成評(píng)論功能

應(yīng)用 comment

# 在 manage.py 的同級(jí)目錄中執(zhí)行
$ python manage.py startapp comment

?在配置文件中注冊(cè) comment 應(yīng)用

# fbckf/settings.py
...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
    'comment',
]
...

模型

?評(píng)論表單內(nèi)容

  • 用戶名稱

  • 文章

  • 評(píng)論內(nèi)容

  • 創(chuàng)建時(shí)間

?編寫(xiě)數(shù)據(jù)模型

# comment/models.py
from django.db import models
from django.contrib.auth.models import User
from blog.models import Article

# Create your models here.
class Comment(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    article = models.ForeignKey(Article, on_delete=models.CASCADE)
    body = models.TextField()
    create_time = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.body[:20]

?數(shù)據(jù)庫(kù)遷移

$ python manage.py makemigrations
$ python manage.py migrate 

URL

# comment/urls.py
from django.urls import path
from . import views

app_name = 'comment'
urlpatterns = [
    path('/<slug>/', views.comment, name='comment'),
]

?在 fbckf/urls.pyinclude() comment 應(yīng)用的 urls.py 文件

# fbckf/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),
    path('comment/', include('comment.urls')),
]

視圖函數(shù)

?視圖函數(shù)將接受道德評(píng)論更新到數(shù)據(jù)庫(kù)表中,并將新數(shù)據(jù)返回給文章頁(yè)面

# comment/views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.models import User
from blog.models import Article
from .models import Comment

def comment(request, slug):
    article = get_object_or_404(Article, title=slug)
    
    if request.method == "POST":
        username = request.POST['username']
        body = request.POST['comment']
        if username and body:
            user = User.objects.get(username=username)
            comment = Comment(user=user, article=article, body=body)
            comment.save()
            return redirect(article)
        else:
            comment = article.comment_set.all()
            return render(request, 'blog/article.html', {'article':article, 'comments':comments})
    return redirect(article)
  • get_object_or_404() 獲取 Article 對(duì)象 ,獲取失敗 返回用戶 404 頁(yè)面

  • redirect() 函數(shù) 重定向到文章詳情頁(yè)面,但是需要修改文章數(shù)據(jù)模型

# blog/models.py
from django.urls import reverse
...
class Article(models.Model):
    ...
    # 返回文章詳情頁(yè)的 url
    def get_absolute_url(self):
        return reverse('blog:article', kwargs={'slug':self.title})

?點(diǎn)開(kāi)文章頁(yè)面是也要獲取評(píng)論列表,因此也要修改 article視圖函數(shù)

# blog/views.py
...
def article(request, slug):
    ...
    comments = article.comment_set.all()
    context['comments'] = comments
    ...
    return render(request, 'blog/article.html', context=context)

?Comment 模型和 Article 模型是 ForeignKey 關(guān)聯(lián)關(guān)聯(lián)關(guān)系,因此使用 article.comment_set.all() 反向獲取所有評(píng)論

修改模板文件

<!-- templates/blog/article.html -->
...
<!-- 判斷用戶是否登陸 -->
{% if username  %}
    <div class="center">
        <button class="btn btn-outline-dark btn-lg" type="button" data-toggle="collapse" href="#post-comment" role="button" aria-expanded="false" aria-controls="post-comment">
            <i class="fa fa-comment-o" aria-hidden="true"></i> 評(píng)論
        </button>
        <button id="like_article" value="{{ article.title }}" type="button" class="btn btn-lg btn-outline-danger" data-toggle="body" data-content="您是第 {{ article.likes|add:1 }} 位喜歡這篇文章的讀者!">
            <i class="fa fa-heart-o" aria-hidden="true"></i>  喜歡
        </button>
        <div class="collapse" id="post-comment">
            <!-- 將表單數(shù)據(jù)以 post 模式提交給后臺(tái) -->
            <form action="{% url 'comment:comment' article.title %}" method="post">
                {% csrf_token %}
                <div class="form-group">
                <textarea name="comment" id="input-comment" cols="30" rows="5" class="form-control"></textarea>    
                <input class="display_none" name="username" value="{{ username }}">
                </div>
                <button class="btn btn-outline-dark" type="submit">發(fā)送</button>
            </form>     
        </div>    
    </div>
{% endif %}
<!-- 判斷是否有評(píng)論 -->
{% if comments %}
<!-- 遍歷評(píng)論列表 -->
{% for comment in comments %}
    <hr>
    <div class="comment-list">
        <div class="comment-detail">
            <div class="row justify-content-start">
                <img src="{% static 'blog/img/carousel2.jpg' %}" class="rounded" alt="user" style="width: 50px; height: 50px;">
                <p class="lead col">{{ comment.user.username }} | {{ comment.create_time }}</p>
            </div> 
            <div class="row justify-content-end"> 
                <p class="col-11">{{ comment.body }}</p>           
            </div>
        </div>
    </div>
{% endfor %}
{% else %}
    <hr>
    <div class="row justify-content-end"> 
        <p class="col-11">暫無(wú)評(píng)論!</p>           
    </div>
{% endif %}
...

?完成后可以重啟服務(wù)器進(jìn)進(jìn)行測(cè)試

總結(jié)

?Markdown 語(yǔ)法簡(jiǎn)潔易懂,普遍用于博客寫(xiě)作,這里也就選擇讓博客支持 Markdown 寫(xiě)作。另外還有富文本編輯器等其他功能可以選擇,不需要一定是 Markdown。

?評(píng)論功能的用戶關(guān)聯(lián)考慮的不是很恰當(dāng),應(yīng)該改為關(guān)聯(lián)其他平臺(tái)用戶,時(shí)間不夠留待下次修改。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,211評(píng)論 3 119
  • 公元710年,唐朝歷史上三位頗具傳奇色彩的政壇女性在同一天斃命。她們分別是野心勃勃的韋皇后,恃寵專橫的安樂(lè)公主,還...
    李小超_9528閱讀 280評(píng)論 1 2
  • 夜里觀青山,思鄉(xiāng)意重; 滿月當(dāng)空照,亮至萬(wàn)里 池中魚(yú)歡蹦,屋中人熟眠 千里路,不淡吾回鄉(xiāng)之意;萬(wàn)丈水,不化吾思鄉(xiāng)之...
    東海散人閱讀 369評(píng)論 0 0
  • 你回眸 一笑 沒(méi)有烈酒 心卻醉了 你停下 走近 沒(méi)有太陽(yáng) 心卻亮了 你俯下身 吻我 沒(méi)有死去 心卻停了 你轉(zhuǎn)身 離...
    冰糖___閱讀 233評(píng)論 3 7
  • 在江的上流有一株櫻花,在爛漫的時(shí)節(jié)里,那一朵朵、一團(tuán)團(tuán)錦簇的粉紅妝點(diǎn)著嫩綠的青草、清澄的流水,樣子十分精致。 那天...
    化濁閱讀 622評(píng)論 2 2

友情鏈接更多精彩內(nèi)容