简说Python,号主老表,Python终身学习者,数据分析爱好者,从18年开始分享Python知识,原创文章227篇,写过Python、SQL、Excel入门文章,也写过Web开发、数据分析文章,老表还总结整理了一份2022Python学习资料和电子书资源,关注后私信回复:2022 即可领取。
一、前情回顾
在前面,我们完成了Django Blog博客发布功能,但是前面发布的博客内容都是富文本的,没有任何样式,输入框也比较简陋,这一节中我们将一起来优化博客发布页面:给博客添加上markdown输入和显示方法。
Django Blog系列文章
Django Blog|02 创建admin账户&settings.py介绍
Django Blog|03 创建一个blog app和Article模型
Django Blog|04 创建blog视图和完成MVT框架开发
Django Blog|06 添加博客详情页视图,显示博客详情
Django Blog|07 引入Bootstrap前端框架,优化页面
二、引入django-mdeditor,实现markdown输入和显示
2.1 基本介绍
django-mdeditor是一个开源的Django组件,基于Editor.md的Django的Markdow编辑器插件应用程序,你可以理解成一个用django写app。
项目地址:https://github.com/pylixm/django-mdeditor
2.2 安装并配置
首先我们需要安装django-mdeditor模块,终端下进入项目目录Project/brief_blog/myblog,然后通过指令进入虚拟环境,然后直接pip install即可安装。
pipenv shell pip install django-mdeditor
安装成功后,需要将django-mdeditor注册到项目设置中,打开Project/brief_blog/myblog/myblog/settings.py文件,找到INSTALLED_APPS,之前我们在里面注册了自己写的blog
app,现在我们将mdeditor注册进去即可,如下所示,加入一行'mdeditor',即可:
INSTALLED_APPS = [ ... 'blog', # 博客app 'mdeditor', # markdown编辑器 ]
除此之外,还需要进一步添加其他相关设置,都添加到settings.py的末尾即可:
# 设置框架 django-mdeditor(django3.0+需要设置) X_FRAME_OPTIONS = 'SAMEORIGIN' # 添加MEDIA的相关配置 图片相关文件会在uploads/editor目录下 MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads') MEDIA_URL = '/media/' # django-mdeditor 设置 MDEDITOR_CONFIGS = { 'default':{ 'width': '90%', # Custom edit box width 'height': 500, # Custom edit box height 'toolbar': ["undo", "redo", "|", "bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase", "|", "h1", "h2", "h3", "h5", "h6", "|", "list-ul", "list-ol", "hr", "|", "link", "reference-link", "image", "code", "preformatted-text", "code-block", "table", "datetime", "emoji", "html-entities", "pagebreak", "goto-line", "|", "help", "info", "||", "preview", "watch", "fullscreen"], # custom edit box toolbar 'upload_image_formats': ["jpg", "jpeg", "gif", "png", "bmp", "webp"], # image upload format type 'image_folder': 'editor', # 图片保存路径 'theme': 'dark', # 工具栏显示主题, dark / default 'preview_theme': 'default', # 预览区显示主题, dark / default 'editor_theme': 'default', # 编辑区显示主题, pastel-on-dark / default 'toolbar_autofixed': True, # 工具栏是否固定在顶部 'search_replace': True, # 是否打开搜索替换 'emoji': True, # 是否打开表情显示 'tex': True, # 是否打开 tex 图表显示 'flow_chart': True, # 是否打开流程图显示 'sequence': True, # 是否打开时序图显示 'watch': True, # 实时预览 'lineWrapping': True, # 是否换行 'lineNumbers': True, # 是否显示行数 'language': 'zh' # 语言 } }
接下来,我们需要到Project/brief_blog/myblog/myblog/urls.py中添加mdeditor路由:
urlpatterns = [ path('admin/', admin.site.urls), # 第一个参数 路由地址 # 第二个参数:include添加blog子应用路由 path('', include('blog.urls')), url(r'mdeditor/', include('mdeditor.urls')) ]
2.3 模块设置
前面配置好django-mdeditor的基本设置,接下来我们需要修改Model模型中的内容字段为markdown类型,我们打开Project/brief_blog/myblog/blog/models.py,原来content字段为models.TextField类型,现在需要修改为mdeditor.fields.MDTextField。
from django.contrib.auth.models import User from django.urls import reverse from mdeditor.fields import MDTextField # 新增 # Create your models here. class Article(models.Model): ... # 和之前一样 # 文章正文 content = MDTextField() # TextField修改为MDTextField ... # 和之前一样
改好models内容后,我们需要重新迁移、建立新的数据映射,更新数据表,在终端虚拟环境中依次执行下面语句即可。
python manage.py makemigrations python manage.py migrate
注意哈,python manage.py xxx的意思是 在python环境中运行manage.py这个文件,所以你执行这个命令的目录里必须有manage.py这个文件,按本系列操作的话,该文件在
Project/brief_blog/myblog
这个目录下。
2.4 查看效果
模型也重构后,我们就可以直接启动项目啦~(可以直接vscode 快捷键Shift F5启动,也可以在终端输入下面指令启动)
python manage.py runserver
启动的项目后,我们通过浏览器访问http://127.0.0.1:8000/admin/,登录admin后台,进入文章管理页面,选择添加文章,就可以看到已经支持markdown输入和实时显示了,nice~
我已经添加过,所以是修改
但是我们会发现前端写博客页面还是没有生效,很简单,我们打开Project/brief_blog/myblog/templates/article_add.html文件,然后添加一行代码即可:
... # 和之前一样 <h1>写博客</h1> <form method="POST"> <!-- 添加csrf_token,防止黑客攻击,获取表单提交内容 csrf Cross Site Request Forgery)攻击 跨站请求伪造攻击 --> {% csrf_token %} {{ form.media }} <!-- 新增一行 --> {{ form.as_p }} <input type="submit" value="发布"> </form> ... # 和之前一样
2.5 文章详情页修改
完成了写文章添加markdown功能后,我们会发现发布的文章显示还是按富文本进行显示的,所以我们还需要修改下文章详情页,让其能解析出markdown内容的格式,至少就像我们在写的时候预览里的格式一样。
从逻辑上来说,就靠django-mdeditor
是肯定能实现的,预览的效果显示到前端页面,我们找到相关方法和渲染的js、html就行。
从项目的issues
中我们可以找到类似的问题,
https://github.com/pylixm/django-mdeditor/issues/5
项目作者也有很好的回答,其实在项目中作者就给我们提供了一个demo,大家感兴趣,也可以去跑一下这个demo。
我们按作者提供的show.html格式修改下我们的article_detial.html即可。
https://github.com/pylixm/django-mdeditor/blob/master/mdeditor_demo_app/templates/show.html
从上图我们知道,需要加载静态文件,但是这个文件从哪里来呢?
有三个地方你可以拿(xia)到(zai)它,最简单的直接在公众号:简说Python后台回复:DjangoBlog,你可以获得目前项目所有源码,在目录myblog/static中就有该文件,复制到自己项目的static目录下即可;
其次就是django-mdeditor项目的github中就有这个文件,直接下载整个项目后,将mdeditor目录内容复制到自己项目的static
目录下即可。
https://github.com/pylixm/django-mdeditor
最后一种获取方式就是去你的python环境包里找,
# 找到自己虚拟环境路径 pipenv --venv
如果你和我一样用pipenv安装的虚拟环境,直接在环境中输入上面指令就能知道自己的虚拟环境安装目录,进入该目录,在这个目录中你能看到mdeditor文件夹lib/python3.10/site-packages/mdeditor/static,直接复制到自己项目中的static目录下即可。
为啥提供三种方式呢,希望大家多思考,学习就是要多思考嘛~
接下来我们就可以修改详情页啦,首先改下Project/brief_blog/myblog/templates/base.html,添加一个可以拓展link的块,注意只新增了三行代码,其他不变。
<!-- 载入静态文件 --> {% load static %} <!-- 新增代码 --> <!doctype html> <html lang="zh-CN"> <head> ... <!-- 和之前一样 --> {% block link %} <!-- 新增代码 --> {% endblock %} <!-- 新增代码 --> <!-- 注意这里 标题内容添加了block标签,这样我们可以在子页面自定义title --> <title> {% block title %} {% endblock %} ... <!-- 和之前一样 -->
然后我们打开文件Project/brief_blog/myblog/templates/article_detial.html,将文件内容替换成下面即可:
{% extends 'base.html' %} <!-- 载入静态文件 --> {% load static %} {% block link %} <!-- markdwon解析css样式 --> <link href="{% static 'mdeditor/css/editormd.min.css' %}" rel="stylesheet"> <link href="{% static 'mdeditor/css/editormd.preview.css' %}" rel="stylesheet"> {% endblock %} {% block title %} 老表爱技术-{{article.title}} {% endblock %} {% block content %} <div class="container"> <div class="row"> <!-- 标题及作者 --> <h1 class="col-12 mt-4 mb-4">{{ article.title }}</h1> <div class="col-12 alert alert-success">作者:{{ article.author }}</div> <blockquote style="margin:0 0 24px;background:#eef0f4;border-left:8px solid #dddfe4;"> {{article.summary}} </blockquote> </div> <!-- 文章正文 --> <div id="content"> <textarea>{{article.content}}</textarea> </div> </div> <script src="{% static 'mdeditor/js/jquery.min.js' %}"></script> <script src="{% static 'mdeditor/js/editormd.min.js' %}"></script> <script src="{% static 'mdeditor/js/lib/marked.min.js' %}"></script> <script src="{% static 'mdeditor/js/lib/prettify.min.js' %}"></script> <script src="{% static 'mdeditor/js/lib/raphael.min.js' %}"></script> <script src="{% static 'mdeditor/js/lib/underscore.min.js' %}"></script> <script src="{% static 'mdeditor/js/lib/sequence-diagram.min.js' %}"></script> <script src="{% static 'mdeditor/js/lib/flowchart.min.js' %}"></script> <script src="{% static 'mdeditor/js/lib/jquery.flowchart.min.js' %}"></script> <script> $(function () { // js 解析markdown editormd.markdownToHTML("content", { //htmlDecode : "style,script,iframe", // you can filter tags decode emoji : true, taskList : true, tex : true, // 默认不解析 flowChart : true, // 默认不解析 sequenceDiagram : true, // 默认不解析 }); $(".reference-link").each(function (i,obj) { console.log(obj) }) }) </script> {% endblock %}
完成修改后,我们刷新页面,会发现,博客详情页面的markdown也正常显示啦~
欢迎大家点赞、在看、转发支持,点击在看,下次可以第一时间收到公众号推文~