Python学习笔记:7.3.6 Django快速建站 - 图文编辑

前言:本文是学习网易微专业的《python全栈工程师 - Django快速建站》课程的笔记,欢迎学习交流。同时感谢老师们的精彩传授!

一、课程目标

  • 注册用户发布博客
  • 使用Markdown编辑器实现图文编辑

二、详情解读

2.1. 注册用户发布博客
2.1.1.开发流程
  • 博客文章的模型类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).表单类继承djangoforms.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
]

运行结果:
Python学习笔记:7.3.6 Django快速建站 - 图文编辑_第1张图片
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>        

运行结果:
Python学习笔记:7.3.6 Django快速建站 - 图文编辑_第2张图片

2.2.使用Markdown编辑器
2.2.1.Markdown
  • 选择Markdown
    – 极简主义、避免许多烦杂功能。
    – 比起使用word更简单快速。
    – 学习难度极低、易读易写。
    – 支持跨平台使用,兼容HTML格式。
    – 更清晰的缓缓文档的结构
    – 可以通过HTMLCSS扩展渲染多种样式,实现一键排版。
    – 利用pandoc可以一键导出wordpdfhtml等多种文本格式。
2.2.2.使用Markdown插件
  • 下载插件,部署到static目录。
  • 编辑:修改blog_post.html
  • 显示:修改content.html

Markdown插件下载地址:http://editor.md.ipandao.com/

实操二: 使用Markdown插件

Step1:将下载好的插件部署到static目录下
Python学习笔记:7.3.6 Django快速建站 - 图文编辑_第3张图片
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路径。

运行结果:
Python学习笔记:7.3.6 Django快速建站 - 图文编辑_第4张图片

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

你可能感兴趣的:(Python全栈工程师学习笔记)