前言:本文是学习网易微专业的《python全栈工程师 - Django快速建站》课程的笔记,欢迎学习交流。同时感谢老师们的精彩传授!
Markdown
编辑器实现图文编辑BlogArticles
,不变blog
应用的forms.py
文件实操一: 实现发布博客功能
Step1
:新建文件myproject/blog/forms.py
,写入BlogArticlesForm
表单类
# -*- coding=utf-8 -*-
from django import forms
from .models import BlogArticles
class BlogArticlesForm(forms.ModelForm):
class Meta:
model = BlogArticles
fields = ('title', 'body')
说明:
1).表单类继承django
的forms.ModelForm
2).表单类对应BlogArticles
模型类
Step2
:新建视图函数blog_post()
from django.shortcuts import render
from .models import BlogArticles
from django.http import HttpResponse # new
# 表示登录用户才有使用的视图函数
from django.contrib.auth.decorators import login_required # new
from .forms import BlogArticlesForm # new
def blog_title(request):
blogs = BlogArticles.objects.all()
return render(request, 'blog/titles.html', locals())
def blog_article(request, article_id):
article = BlogArticles.objects.get(id=article_id)
pub = article.publish
return render(request, 'blog/content.html', {'article': article, 'publish': pub})
# new
@login_required()
def blog_post(request):
if request.method == 'GET':
blog_form = BlogArticlesForm()
return render(request, 'blog/blog_post.html', {'blog_form': blog_form})
if request.method == 'POST':
blog_form = BlogArticlesForm(request.POST)
# 表单数据验证通过
if blog_form.is_valid():
# 获取表单数据
cd = blog_form.cleaned_data
try:
new_blog = blog_form.save(commit=False)
new_blog.author = request.user
new_blog.save()
return HttpResponse('1')
except Exception as e:
return HttpResponse('-1')
else:
return HttpResponse('0')
说明:
1).登录用户才能发布博客,所以引入login_required
,用来装饰视图函数
2).引入HttpResponse
,返回发布结果
3).引入BlogArticlesForm
表单类。
4).blog_form.save(commit=False)
获取一个未提交的博客表单类实例
5).博客的作者是当前已登录的请求用户request.user
。
Step3
:新建模板文件myproject/templates/blog/blog_post.html
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}Post blog{% endblock %}
{% block content %}
<div class="row text-center">
<form action="." class="form-horizontal" method="post">
<div class="row">
<div class="col-md-2 text-right">标题:div>
<div class="col-md-10 text-left">{{ blog_form.title }}div>
div>
<div class="row">
<div class="col-md-2 text-right">内容:div>
<div class="col-md-10 text-left">{{ blog_form.body }}div>
div>
<div class="row">
<input type="button" value="发布博客" class="btn btn-primary btn-lg" onclick="post_blog()">
div>
form>
div>
<script src="{% static 'js/jquery-3.4.1.min.js' %}">script>
<script src="{% static 'js/layer.js' %}">script>
<script src="{% static 'js/csrf.js' %}">script>
<script>
function post_blog() {
var title = $('#id_title').val()
var body = $('#id_body').val()
$.ajax({
url: "{% url 'blog:blog_post' %}",
type: 'POST',
data: {'title': title, 'body': body},
success: function(e) {
if (e == '1') {
layer.msg('发布成功')
} else if(e == '-1') {
layer.msg('服务器忙')
} else {
layer.msg('请检查输入的内容,不允许空.')
}
}
})
}
script>
{% endblock %}
说明:
1).$('#id_title').val()
里的id_title
是表单里默认的,如果不知道id
值是什么,可以打印出来看看。
Step4
:配置发布博客路由。编辑文件myproject/blog/urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.blog_title, name='blog_title'),
path('/' , views.blog_article, name='blog_article'),
path('blog-post/', views.blog_post, name='blog_post'), # new
]
运行结果:
Step5
:添加发布博客入口。编辑myproject/templates/header.html
文件
.
.
.
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
<li>
<div class="dropdown">
<button class="btn btn-default dropdown-toggle"
type="button"
id="dropdownMenu"
data-toggle="dropdown">
{{ user.username }}
<span class="caret">span>
button>
<ul class="dropdown-menu">
<li><a href="{% url 'blog:blog_post' %}">发布博客a>li>
<li><a href="{% url 'account:password_change' %}">修改密码a>li>
<li><a href="{% url 'account:aboutme' %}">个人信息a>li>
ul>
div>
li>
<li><a href="{% url 'account:user_logout' %}">退出a>li>
{% else %}
<li><a href="{% url 'account:user_login' %}">登录a>li>
{% endif %}
ul>
Markdown
编辑器Markdown
Markdown
word
更简单快速。HTML
格式。HTML
和CSS
扩展渲染多种样式,实现一键排版。pandoc
可以一键导出word
、pdf
、html
等多种文本格式。Markdown
插件static
目录。blog_post.html
content.html
Markdown
插件下载地址:http://editor.md.ipandao.com/
实操二: 使用Markdown
插件
Step1
:将下载好的插件部署到static
目录下
Step2
:修改文件myproject/templates/blog/blog_post.html
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}Post blog{% endblock %}
{% block style %}
<link rel="stylesheet" href="{% static 'editor/css/editormd.min.css' %}" />
{% endblock %}
{% block content %}
<div class="row text-center">
<form action="." class="form-horizontal" method="post">
<div class="row">
<div class="col-md-2 text-right">标题:div>
<div class="col-md-10 text-left">{{ blog_form.title }}div>
div>
<div class="row">
<div class="col-md-2 text-right">内容:div>
<div id="editormd" class="col-md-10 text-left">
<textarea style="display:none;" id="id_body">textarea>
div>
div>
<div class="row">
<input type="button" value="发布博客" class="btn btn-primary btn-lg" onclick="post_blog()">
div>
form>
div>
<script src="{% static 'js/jquery-3.4.1.min.js' %}">script>
<script src="{% static 'js/layer.js' %}">script>
<script src="{% static 'js/csrf.js' %}">script>
<script src="{% static 'editor/editormd.min.js' %}">script>
<script>
function post_blog() {
var title = $('#id_title').val()
var body = $('#id_body').val()
$.ajax({
url: "{% url 'blog:blog_post' %}",
type: 'POST',
data: {'title': title, 'body': body},
success: function(e) {
if (e == '1') {
layer.msg('发布成功', {icon:1, time:1000})
} else if(e == '-1') {
layer.msg('服务器忙', {icon:2, time:1000})
} else {
layer.msg('请检查输入的内容,不允许空.', {icon:2, time:1000})
}
}
})
}
// new
$(function(){
var editor = editormd('editormd', {
width: '100%',
height: 640,
syncScrolling: 'single',
path: "{% static 'editor/lib/' %}"
});
});
script>
{% endblock %}
说明:
1).记得引入 markdown的css文件。如果引入不生效,检查templates/base.html
文件下,是否有如下代码中的{%block style %}{% endblock %}
:
{% load staticfiles %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{% static 'css/bootstrap.css' %}">
{%block style %}{% endblock %}
head>
<body>
{% include 'header.html' %}
<div class="container">
{% block content %}{% endblock %}
div>
{% include 'footer.html' %}
{% block javascript %}{% endblock %}
body>
html>
2).修改原来的博客文章输入框。别忘记id="editormd"
和id="id_body"
了。
2).记得引入文件editormd.min.js
3).初始化Markdown editor
,注意path
路径。
Step3
:显示Markdown
格式的博客。
修改文件myproject/templates/blog/content.html
{% extends 'base.html' %}
{% block title %}article {% endblock %}
{% block content %}
<div class="row text-center">
<h1>{{ article.title }}h1>
<p class="text-center">
<span>{{ article.author.username }}span>
<span style="margin-left: 20px">{{ publish }}span>
p>
<link rel="stylesheet" href="{% static 'editor/css/editormd.preview.css' %}">
<div id="editormd-view">
<textarea id="append-test" style="display:none;">{{ article.body }}textarea>
div>
div>
<script src="{% static 'js/jquery-3.4.1.min.js' %}">script>
<script src="{% static 'editor/lib/marked.min.js' %}">script>
<script src="{% static 'editor/lib/prettify.min.js' %}">script>
<script src="{% static 'editor/lib/raphael.min.js' %}">script>
<script src="{% static 'editor/lib/underscore.min.js' %}">script>
<script src="{% static 'editor/lib/sequence-diagram.min.js' %}">script>
<script src="{% static 'editor/lib/flowchart.min.js' %}">script>
<script src="{% static 'editor/lib/jquery.flowchart.min.js' %}">script>
<script src="{% static 'editor/editormd.min.js' %}">script>
<script>
$(function(){
editormd.markdownToHTML('editormd-view', {
htmlDecode: 'style, script, iframe',
emoji: true,
taskList: true,
text: true,
flowChart: true,
sequenceDiagram: true,
})
})
script>
{% endblock %}
{% block ad %}
{% load static %}
<img src="{% static './images/djbook.jpg' %}" width="400" alt="">
{% endblock %}
说明:textarea
标签里的内容{{ article.body }}
两边不能有空格,因为用的是Markdown
插件,空格是有意义的,所以会影响博客的内容。
Step4
:发布博客成功返回博客列表页。
修改文件myproject/templates/blog/blog_post.html
.
.
.
<script>
function post_blog() {
var title = $('#id_title').val()
var body = $('#id_body').val()
$.ajax({
url: "{% url 'blog:blog_post' %}",
type: 'POST',
data: {'title': title, 'body': body},
success: function(e) {
if (e == '1') {
layer.msg('发布成功', {icon:1, time:1000})
// 新增下面这行代码,
location.href = "{% url 'blog:blog_title' %}";
} else if(e == '-1') {
layer.msg('服务器忙', {icon:2, time:1000})
} else {
layer.msg('请检查输入的内容,不允许空.', {icon:2, time:1000})
}
}
})
}
// new
$(function(){
var editor = editormd('editormd', {
width: '100%',
height: 640,
syncScrolling: 'single',
path: "{% static 'editor/lib/' %}"
});
});
</script>
.
.
.
Markdown