久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Django-Vue搭建個人博客:Markdown正文

 風聲之家 2021-03-18

原創(chuàng) 杜賽 杜賽說編程

博客文章需要排版,,否則難以凸顯標題,、正文,、注釋等內(nèi)容之間的區(qū)別,。作為博客寫手來說,,比較流行且好用的排版是采用 Markdown 語法,。

嚴格來說, Markdown 是一種排版標注規(guī)則,。它將兩個星號包裹的文字標注為重要文本(通常也就是粗體字),比如原始文本中的 **Money** ,,在 Markdown 語法中應該被”渲染“為粗體,,也就是 Money 。類似的還有斜體,、代碼塊,、表格、公式等注釋,,就請讀者自行了解了,。

關于 Markdown[1] 的簡單介紹。

”渲染“ Markdown 也就是把原始文本中的注釋轉(zhuǎn)化為前端中真正被用戶看到的 HTML 排版文字,。渲染過程可以在前端也可以在后端,,本文將使用后端渲染,,以便你理解 DRF 的相關知識。

模型和視圖

為了將博文的 Markdown 正文渲染為 html 標簽,,首先給文章模型添加一個 get_md() 方法:

# article/models.py

from markdown import Markdown
...

class Article(models.Model):
    ...
    
    # 新增方法,,將 body 轉(zhuǎn)換為帶 html 標簽的正文
    def get_md(self):
        md = Markdown(
            extensions=[
                'markdown.extensions.extra',
                'markdown.extensions.codehilite',
                'markdown.extensions.toc',
            ]
        )
        md_body = md.convert(self.body)
        # toc 是渲染后的目錄
        return md_body, md.toc

方法返回了包含了兩個元素的元組,分別為已渲染為 html 的正文目錄,。

這些渲染后的數(shù)據(jù),,在文章詳情接口是需要的,但是在列表接口卻沒太有必要,,因此又要用到視圖集根據(jù)請求方式動態(tài)獲取序列化器的技術了:

# article/views.py

from article.serializers import ArticleDetailSerializer

...

# 新增 get_serializer_class() 方法
class ArticleViewSet(viewsets.ModelViewSet):
    ...

    def get_serializer_class(self):
        if self.action == 'list':
            return ArticleSerializer
        else:
            return ArticleDetailSerializer

序列化器 ArticleDetailSerializer  還沒有寫,,這就來搞定它。

序列化器

因為文章列表接口詳情接口只有一點點返回字段的區(qū)別,,其實大部分功能還是一樣的,。那么被面向?qū)ο缶幊萄盏哪悖鞍阉橄蟪筛割?!?應該可以脫口而出:

# article/serializers.py

...

# 將已有的 ArticleSerializer 里的東西全部挪到這個 ArticleBaseSerializer 里來
# 除了 Meta 類保留
class ArticleBaseSerializer(serializers.HyperlinkedModelSerializer):
    author = ...
    category = ...
    category_id = ...
    tags = ...

    def to_internal_value(self, data):
        ...

    def validate_category_id(self, value):
        ...

# 保留 Meta 類
# 將父類改為 ArticleBaseSerializer
class ArticleSerializer(ArticleBaseSerializer):
    class Meta:
        model = Article
        fields = '__all__'
        extra_kwargs = {'body': {'write_only'True}}

與 Django 表單類似,,你可以繼承擴展和重用序列化器。就像上面的代碼一樣,,在父類上聲明一組通用的字段或方法,,然后在許多序列化程序中使用它們。

但是內(nèi)部類 class Meta 比較特殊,,它不會隱式從父類繼承,。雖然有辦法讓它隱式繼承,但這是不被推薦的,,你應該顯式聲明它,,以使得序列化器的行為更清晰。

另外,,如果你覺得在列表接口連 body 字段也不需要顯示的話,,你可以傳入 extra_kwargs 使其變成僅可寫卻不顯示的字段。

把這些代碼重構(gòu)的準備工作都搞定之后,,就可以正式寫這個新的 ArticleDetailSerializer了:

# article/serializers.py

...

# 注意繼承的父類是 ArticleBaseSerializer
class ArticleDetailSerializer(ArticleBaseSerializer):
    # 渲染后的正文
    body_html = serializers.SerializerMethodField()
    # 渲染后的目錄
    toc_html = serializers.SerializerMethodField()

    def get_body_html(self, obj):
        return obj.get_md()[0]

    def get_toc_html(self, obj):
        return obj.get_md()[1]

    class Meta:
        model = Article
        fields = '__all__'

body_html ,、 toc_html 這兩個渲染后的字段是經(jīng)過加工后的數(shù)據(jù),不存在于原始的數(shù)據(jù)中,。為了將這類只讀的附加字段添加到接口里,,就可以用到 SerializerMethodField() 字段了。比如說上面代碼中的 body_html 字段,,它會自動去調(diào)用 get_body_html() 方法,,并將其返回結(jié)果作為需要序列化的數(shù)據(jù)。方法中的 obj 參數(shù)是序列化器獲取到的 model 實例,,也就是文章對象了,。

這樣就大功告成了,,讀者自己測試一下,順利的話詳情接口就可以返回 Markdown 渲染后的數(shù)據(jù)了,。

記得原始文本應該用 Markdown 語法編寫,。成功的話 body_html 字段返回的是帶有 html 標簽的文本。

代碼重構(gòu)得太早可能會導致某些不必要的抽象,,太晚又可能堆積太多”屎山“而無從下手,。理想情況下的重構(gòu)是隨著項目的開發(fā)同時進行的,在合適的節(jié)點進行合適的抽象,,看著代碼逐漸規(guī)整,,你也會相當有成就感。

另一個問題是,,有時候你可能出于版權(quán)方面的考慮不愿意將原始的 Markdown 文章數(shù)據(jù)給任意用戶,,那么這里只要做一次鑒權(quán),根據(jù)用戶的權(quán)限選用不同的序列化器即可,。(非管理員不返回原始文章數(shù)據(jù))

參考資料

[1]

關于 Markdown: https://www./article/20/

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多