从零开始做个人网站(5)

写在前面:

由于作者仅仅是自学,且是独自做这个项目,代码中出现不少漏洞、错误、累赘或常识问题是难免的,作者也在不断努力学习中,请各位看官多提意见,轻喷~


基本信息

1. 项目环境

Python 3.10.7

Django 4.2

编辑器:VSCode

操作系统:Windows 10

2. 项目背景

正好近一段时间在自学 Django,突发奇想不妨试着做个个人网站练练手吧~

3. 项目构思

暂定为:登录系统 + 个人主页 + 个人博客 + 个人作品


项目代码

今天的任务是做完登录系统的前端模板~

1. 重置密码页面前端代码

准备工作:

1. 在 /LZLBlog/login/templates/login/ 新建 reset.html

2. 在 /LZLBlog/login/templates/login/ 新建 resetpassword.html

3. 在 /LZLBlog/login/static/login/css 新建 reset.css

3. 在 /LZLBlog/login/static/login/css 新建 resetpassword.css

大致结构:

  1. reset.html 负责获取用户输入的邮箱并发送修改密码链接
  2. resetpassword.html 负责获取用户新修改的密码

reset.html 思路:

  1. 如果有错误提示信息,那么先弹出错误提示信息
  2. 显示网站 logo 图片
  3. 显示验证码
  4. 显示邮箱输入框
  5. 显示提交按钮

resetpassword.html 思路:

  1. 如果有错误提示信息,那么先弹出错误提示信息
  2. 显示网站 logo 图片
  3. 显示验证码
  4. 显示密码输入框
  5. 显示确认密码输入框
  6. 显示提交按钮

重置密码页面前端代码:

/LZLBlog/login/templates/login/reset.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
    <link href="{% static 'login/css/reset.css' %}" rel="stylesheet"/> 
    <link href="{% static 'login/css/verify.css' %}" rel="stylesheet"/> 
    <link href="{% static 'login/image/favicon.ico' %}" rel="shortcut icon"/>
    <title>LZLSite | 修改密码-邮件确认</title>
</head>

{% if message %}
<div class="alert alert-warning alert-dismissible fade show" style="width:1000px;padding-left: 50px;margin:0 auto">
    <button type="button" class="close" data-dismiss="alert">&times;</button>
    <strong>{{ message }}</strong>
</div>
{% endif %}

<body>
    <div class="container">
        <div class="login-group">
            <form class="form-login" action="/login/reset/" method="post">
                {% csrf_token %}

                <!-- 网站 logo 图片 -->
                <div class="logo-image"></div>

                <!-- 拖动滑块验证 -->
                <div class="captcha-group">
                    <div id="mpanel1"></div>
                </div>

                <!-- 邮件 -->
                <div class="email-group"> 
                    <input type="text" name="email" class="email-input" id="email-input" placeholder="请输入邮件">
                </div>

                <!-- 提交按钮 -->
                <div class="submit-button-container">
                    <button type="submit" class="submit-button" id="submit-button" disabled="disabled">去邮件修改密码</button>
                </div>
            </form>
        </div>
    </div>
    
    <script type="text/javascript" src="{% static 'login/js/jquery.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/popper.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/bootstrap.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/verify/verify.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/show_verify.js' %}"></script>
</body>
</html>

/LZLBlog/login/static/login/css/reset.css

body {
    height: 100%;
    background-image: url('../image/bg.png');
    background-repeat: no-repeat;
    background-attachment: fixed;  
}

.container {
    background-color: white;
    border-radius: 10px;
    text-align: center;
    width: 450px;
    height: 550px;
    position: absolute;
    left: 50%;
    top: 50%;
    margin: -275px 0 0 -225px;
}

.logo-image {
    width: 354px;
    height: 175px;
    background-image: url("../image/favicon.png");
    display: block;
    margin: auto;
    margin-top: 40px;
}

.email-group {
    margin-top: 30px;
}

input.email-input {
    position: relative;
    box-shadow: 0 1px 4px 1px #999999;
    font-size: 18px;
    width: 360px;
    height: 48px;
    padding-left: 20px;
    border: 1px solid darkgrey;
    border-radius: 3px;
}

input.email-input:focus, input.email-input:hover {
    outline: 0;
    border: 2px solid rgb(0,172,194); 
    box-shadow: 0 1px 4px 1px #b1fff8;
}

.submit-button-container {
    display: block;
    margin-top: 50px;
}

button.submit-button {
    width: 320px;
    height: 50px;
    border-radius: 8px;
    font-size: 20px;
    color: white;
    font-weight: bold;
    background-color: rgb(2, 180, 204);
    box-shadow: 0px 5px 1px rgb(0, 116, 131);
    border: 0px;
}

button.submit-button[disabled] {
    width: 320px;
    height: 50px;
    border-radius: 8px;
    font-size: 20px;
    color: white;
    font-weight: bold;
    background-color: rgb(150, 150, 150);
    box-shadow: 0px 5px 1px rgb(85, 85, 85);
    border: 0px;
}

button.submit-button[disabled]:hover, button.submit-button[disabled]:active {
    width: 320px;
    height: 50px;
    border-radius: 8px;
    font-size: 20px;
    color: white;
    font-weight: bold;
    background-color: rgb(150, 150, 150);
    box-shadow: 0px 5px 1px rgb(85, 85, 85);
    border: 0px;
}

button.submit-button:hover, .submit-button:active {
    outline: 0;
    background-color: rgb(2, 200, 226);
    box-shadow: 0px 5px 1px rgb(0, 134, 151);
}

.captcha-group {
    margin-top: 30px;
    margin-left: 30px;
}

/LZLBlog/login/templates/login/resetpassword.html

{% load static %}
{% load extratag %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
    <link href="{% static 'login/css/resetpassword.css' %}" rel="stylesheet"/> 
    <link href="{% static 'login/css/verify.css' %}" rel="stylesheet"/> 
    <link href="{% static 'login/image/favicon.ico' %}" rel="shortcut icon"/>
    <title>LZLSite | 修改密码</title>
</head>

{% if message %}
<div class="alert alert-warning alert-dismissible fade show" style="width:1000px;padding-left: 50px;margin:0 auto">
    <button type="button" class="close" data-dismiss="alert">&times;</button>
    <strong>{{ message }}</strong>
</div>
{% endif %}

<body>
    <div class="container">
        <div class="login-group">
            <form class="form-login" action="{{ "/login/resetpassword/?code="|addstr:code }}" method="post">
                {% csrf_token %}

                <!-- 网站 logo 图片 -->
                <div class="logo-image"></div>

                <!-- 拖动滑块验证 -->
                <div class="captcha-group">
                    <div id="mpanel1"></div>
                </div>

                <!-- 新密码 -->
                <div class="password-group">
                    <input type="password" name="password" class="password-input" id="password-input" placeholder="请输入新密码">
                </div>

                <!-- 重复新密码 -->
                <div class="password-again-group">
                    <input type="password" name="password_repeat" class="password-again-input" id="password-again-input" placeholder="请再次输入新密码">
                </div>

                <!-- 提交按钮 -->
                <div class="submit-button-container">
                    <button type="submit" class="submit-button" id="submit-button" disabled="disabled">修改密码</button>
                </div>
            </form>
        </div>
    </div>
    
    <script type="text/javascript" src="{% static 'login/js/jquery.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/popper.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/bootstrap.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/verify/verify.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/show_verify.js' %}"></script>

</body>
</html>

/LZLBlog/login/static/login/css/resetpassword.css

body {
    height: 100%;
    background-image: url('../image/bg.png');
    background-repeat: no-repeat;
    background-attachment: fixed;  
}

.container {
    background-color: white;
    border-radius: 10px;
    text-align: center;
    width: 450px;
    height: 600px;
    position: absolute;
    left: 50%;
    top: 50%;
    margin: -275px 0 0 -225px;
}

.logo-image {
    width: 354px;
    height: 175px;
    background-image: url("../image/favicon.png");
    display: block;
    margin: auto;
    margin-top: 40px;
}

.password-group {
    margin-top: 30px;
}

input.password-input {
    font-size: 18px;
    box-shadow: 0 1px 4px 1px #999999;
    width: 360px;
    height: 48px;
    padding-left: 20px;
    border: 1px solid darkgrey;
    border-radius: 3px;
}

input.password-input:focus, input.password-input:hover {
    outline: 0;
    border: 2px solid rgb(0,172,194); 
    box-shadow: 0 1px 4px 1px #b1fff8;
}

.password-again-group {
    margin-top: 30px;
}

input.password-again-input {
    font-size: 18px;
    box-shadow: 0 1px 4px 1px #999999;
    width: 360px;
    height: 48px;
    padding-left: 20px;
    border: 1px solid darkgrey;
    border-radius: 3px;
}

input.password-again-input:focus, input.password-again-input:hover {
    outline: 0;
    border: 2px solid rgb(0,172,194); 
    box-shadow: 0 1px 4px 1px #b1fff8;
}

.submit-button-container {
    display: block;
    margin-top: 50px;
}

button.submit-button {
    width: 320px;
    height: 50px;
    border-radius: 8px;
    font-size: 20px;
    color: white;
    font-weight: bold;
    background-color: rgb(2, 180, 204);
    box-shadow: 0px 5px 1px rgb(0, 116, 131);
    border: 0px;
}

button.submit-button[disabled] {
    width: 320px;
    height: 50px;
    border-radius: 8px;
    font-size: 20px;
    color: white;
    font-weight: bold;
    background-color: rgb(150, 150, 150);
    box-shadow: 0px 5px 1px rgb(85, 85, 85);
    border: 0px;
}

button.submit-button[disabled]:hover, button.submit-button[disabled]:active {
    width: 320px;
    height: 50px;
    border-radius: 8px;
    font-size: 20px;
    color: white;
    font-weight: bold;
    background-color: rgb(150, 150, 150);
    box-shadow: 0px 5px 1px rgb(85, 85, 85);
    border: 0px;
}

button.submit-button:hover, .submit-button:active {
    outline: 0;
    background-color: rgb(2, 200, 226);
    box-shadow: 0px 5px 1px rgb(0, 134, 151);
}

.captcha-group {
    margin-top: 30px;
    margin-left: 30px;
}

2. 用户主页页面前端代码

准备工作:

1. 在 /LZLBlog/login/templates/login/ 新建 index.html

2. 在 /LZLBlog/login/static/login/css 新建 index.css

3. 在 /LZLBlog/login/static/login/js 新建 custom.js

4. 在 /LZLBlog/login/static/login/js 新建 user_index.js

大致结构:

  1. 如果用户主页的这个用户不存在,显示错误提示,直接结束
  2. 显示网站导航栏
  3. 显示用户头像(无限制时,点击可以上传更换头像)
  4. 显示用户名
  5. 显示个人签名(无限制时,鼠标悬浮会有提示,点击可以更改签名)
  6. 显示个人介绍(无限制时,点击按钮可以使用 富文本编辑器 更改个人介绍)
  7. 无限制时,显示个人设置(包括修改密码和登出)

用户主页页面前端代码:

/LZLBlog/login/templates/login/index.html

{% load static %}
{% load extratag %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
    <link href="{% static 'login/js/sweetalert/sweetalert.min.css' %}" rel="stylesheet" />
    <link href="{% static 'login/css/index.css' %}" rel="stylesheet"/>
    <link href="{% static 'blog/css/font-awesome.min.css' %}" rel="stylesheet"/>
    <link href="{% static 'login/image/favicon.ico' %}" rel="shortcut icon"/>
    {% if user %}
        <title>LZLSite | 用户 {{ user.name }} 的个人界面</title>
    {% else %}
        <title>LZLSite | 未知用户</title>
    {% endif %}
</head>

{% csrf_token %}

{% if not user %}
<body>
    <div class="container">
        <h1 style="font-size:40px; text-align: center; margin-top: 60px; padding-top: 60px; padding-bottom: 60px;font-weight: bold; ">抱歉,该用户不存在!</h1>
    </div>
</body>
{% else %}

<body>
    <header class="header-area">
        <div class="header-container">
            <div class="row d_flex">
                <div class="col-md-12 col-sm-12">
                    <div class="navbar-area">
                        <nav class="site-navbar">
                            <a class="logo" href="/index/index/"> LZLSITE </a>
                            <i class="fa fa-envelope" aria-hidden="true"><a class="contactlink" href="https://mail.163.com/">lzl20220405@163.com</a></i>
                            
                            <ul>
                                <li><a href="/index/index/">主页</a></li>
                                <li><a href="/index/about/">关于作者</a></li>
                                <li><a href="/blogs/list/1/">博客</a></li>
                                <li><a href="/index/index/">其他作品</a></li>
                             </ul>
                        </nav>
                        <ul class="email text_align_right">
                            {% if login %}
                                <a href={{ "/login/index/"|addstr:username|addstr:"/" }} target="_blank"><img class="avatar-detail" src="{{ user.avatar.url }}"></img></a>
                            {% else %}
                                <li><a class="login_button" href="/login/login/" target="_blank">登录</a></li>
                            {% endif %}
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </header>

    <div class="container">
        {% if not limits %}
            <div class="front-detail">
                <!-- 头像 -->
                <div id="avatardiv" onmouseover="avatar_mouseover()" onmouseout="avatar_mouseout()" onclick="getImg()">
                    <img class="avatar" id="avatar" src="{{ user.avatar.url }}" data-toggle="tooltip" title="点击更换头像" data-placement="left">
                </div>
                
                <!-- 用户名-->
                <p class="username">{{ user.name }}</p>

                <!-- 头像上传表单 -->
                <form action={{ "/login/index/"|addstr:user.name|addstr:"/" }} method="POST" id="avatar-form" enctype="multipart/form-data">
                    {% csrf_token %}
                    <input id="avatar-upload" type="file" name="avatar" accept="image/*" style="display: none" onchange="uploadImg()">
                </form>

                <!-- 修改个人签名模态框 -->
                <div class="modal fade" id="description-modal">
                    <div class="modal-dialog">
                        <div class="modal-content">
                            <div class="modal-header">
                                <h4 class="modal-title">修改个人签名</h4>
                                <button type="button" class="close" data-dismiss="modal"></button>
                            </div>

                            <div class="modal-body">
                                <form action={{ "/login/index/"|addstr:user.name|addstr:"/" }} method="POST" id="description-form">
                                    {% csrf_token %}
                                    <input id="small-description-upload" type="text" name="small_description" value="{{ user.small_description }}" autocomplete="off">
                                </form>
                            </div>

                            <div class="modal-footer">
                                <button type="button" class="btn btn-primary" data-dismiss="modal" onclick="uploadDescription()">保存</button>
                            </div> 
                        </div>
                    </div>
                </div>

                <!-- 个人签名 -->
                <p class="small-description" onclick="show_SmallDescriptionModal()" data-toggle="tooltip" title="点击更换签名" data-placement="right">{{ user.small_description }}</p>
                <hr class="line1">
            </div>

            <div class="user-description">
                <div id="user-detail-group">
                    <!-- 个人介绍展示区 -->
                    <p class="user-detail-title">个人介绍</p>
                    <button onclick="turn_editor_visible()" class="turn-editor-button">去编辑</button>
                    <div id="user-detail" class="editor-content-view">{{ user.big_detail|safe }}</div>
                </div>

                <div id="editor-wrapper" class="editor-space" style="display: none;">
                    <!-- 个人介绍编辑区 -->
                    <p class="user-detail-write-title">编辑个人介绍</p>
                    <form action={{ "/login/index/"|addstr:user.name|addstr:"/" }} method="POST">
                        {% csrf_token %}
                        <div class="button-wrapper">
                            <button type="submit" class="save-text-button">保存</button>
                            <button type="button" onclick="turn_text_visible()" class="turn-text-button">取消</button>
                        </div>
                        <textarea name="big_detail" id="editor-space">{{ user.big_detail|safe }}</textarea>
                    </form>
                </div>
                <hr class="line2">
            </div>
            
            <div class="user-settings">
                <!-- 个人设置 -->
                <p class="user-settings-title">个人设置</p>
                <button type="button" onclick="logout()" class="logout-button">登出</button>
                <button type="button" onclick="reset_password()" class="reset-password-button">修改密码</button>
                <hr class="line3">
            </div>
            
        {% else %}
            <!-- 当访问其他用户主页时展示的页面 -->
            <div class="front-detail">
                <!-- 头像 -->
                <div id="avatardiv">
                    <img class="avatar" id="avatar" src="{{ user.avatar.url }}">
                </div>

                <!-- 用户名 -->
                <p class="username">{{ user.name }}</p>

                <!-- 用户签名 -->
                <p class="small-description">{{ user.small_description }}</p>
                <hr class="line1">
            </div>

            <div class="user-description">
                <!-- 个人介绍 -->
                <div id="user-detail-group">
                    <p class="user-detail-title">个人介绍</p>
                    <div id="user-detail" class="editor-content-view">{{ user.big_detail|safe }}</div>
                </div>
                <hr class="line2-end">
            </div>
        {% endif %}
    </div>

    <script type="text/javascript" src="{% static 'login/js/jquery.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/popper.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/bootstrap.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/sweetalert/angular.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/sweetalert/angular-SweetAlert.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/sweetalert/sweetalert.min.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/custom.js' %}"></script>
    <script type="text/javascript" src="{% static 'login/js/tinymce/tinymce.min.js' %}"></script>

    {% if not limits %}
        <script type="text/javascript" src="{% static 'login/js/user_index.js' %}"></script>
        <script type="text/javascript">
            window.history.replaceState(null, null, window.location.href);

            function startChange(obj,speed,target){
                clearInterval(timer);
                speed = target>alpha?speed:-speed;
                timer = setInterval(function(){
                if(alpha <= target){
                    clearInterval(timer);
                    var avatar_img = document.getElementById('avatar');
                    if (avatar_type == 0){
                        avatar_img.src = "{% static 'login/image/upload_avatar_image.png' %}";
                        alpha = 100;
                        avatar_type = 1;
                    }
                    else{
                        avatar_img.src = "{{ user.avatar.url }}";
                        alpha = 100;
                        avatar_type = 0;
                    }
                }
                else{
                    alpha += speed;
                }
                obj.style.opacity=alpha/100;
                obj.style.filter="alpha(opacity:"+alpha+")";
                },20);
            }
        </script>
    {% endif %}
</body>

{% endif %}
</html>

注意:这里用到了 自定义过滤器,后面会介绍

/LZLBlog/login/static/login/css/index.css

@import url('https://fonts.googleapis.com/css?family=Poppins:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i');
@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700,900&display=swap');
@import url('https://fonts.googleapis.com/css?family=Raleway:400,500,600,700,800,900&display=swap');

html {
    scroll-behavior: smooth;
    overflow-x: hidden;
}

body {
    color: #666666;
    font-size: 14px;
    font-family: 'Poppins', sans-serif;
    line-height: 1.80857;
    font-weight: normal;
    overflow-x: hidden;
}


ul,
li,
ol {
    margin: 0px;
    padding: 0px;
    list-style: none;
}

a {
    color: #1f1f1f;
    text-decoration: none !important;
    outline: none !important;
    -webkit-transition: all .3s ease-in-out;
    -moz-transition: all .3s ease-in-out;
    -ms-transition: all .3s ease-in-out;
    -o-transition: all .3s ease-in-out;
    transition: all .3s ease-in-out;
}


a.logo  {
    color: #fff;
    font-size: 40px;
    margin-right: 60px;
    font-weight: bold;
    text-transform: uppercase;
    text-align: center;
    display: block;
}

.header-container {
    width: 100%;
}

img {
    max-width: 100%;
    height: auto;
}

:focus {
    outline: 0;
}

.d_flex {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
}

.header-area {
    width: 100%;
    background: #39b54a;
}

.navbar-area {
    background: #39b54a;
    height: 112px;
    display: flex;
    justify-content: space-around;
    align-items: center;
}

.site-navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.site-navbar ul {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
}

i {
    color: #fff;
    display: inline-block;
}

a.contactlink {
    color: #fff;
    font-size: 17px;
    display:inline-block;
    font-family: 'Poppins';
    text-decoration: none;
    margin-right: 150px;
    margin-left: 10px;
}

.site-navbar ul li a {
    color: #fff;
    font-size: 17px;
    display: block;
    text-decoration: none;
    text-transform: uppercase;
}

.site-navbar ul li {
    padding-right: 50px;
}

.site-navbar ul li:last-child {
    padding-right: 0;
}

.site-navbar ul li a:hover {
    color: #141313;
}
.site-navbar ul li a.active {
    color: #141313;
}

.text_align_right {
    text-align: right;
}

ul.email {
    text-align: right;
}

ul.email li {padding-right: 65px; display: inline-block;}
ul.email li:last-child {padding-right: 0px;}
ul.email li a {
    color: #ffff; 
    font-weight: 500;
    font-size: 17px;
    text-transform: uppercase;
}

ul.email li a i {
    color: #ffff;
    font-size: 19px;
    padding-right: 10px;
}

img.avatar-detail {
    width: 50px;
    height: 50px;
    border-radius: 5px;
    margin-right: 50px;
    float: right;
}

a.login_button {
    /*border: 1px solid white;*/
    background-color: #1680e4;
    border-radius: 5px;
    padding-left: 20px;
    padding-right: 20px;
    padding-top: 10px;
    padding-bottom: 10px;
}

a.login_button:hover{
    outline: 0;
    background-color:  #bce1ff;
    color: black;
}

#user-detail{
    font-size: 18px;
    color: black;
    line-height: 2;
}

#user-detail blockquote {
    border-left: 2px solid grey;
    margin-left: 1.5rem;
    padding-left: 1rem;
}

.container {
    background: #fff;
    box-shadow: 3px 3px 62px rgba(13, 3, 3, 0.10);
    margin-top: 80px;
}

.front-detail {
    padding-top: 50px;
    margin-top: 40px;
    margin-left: 50px;
    margin-right: 50px;
}

#avatar {
    display: inline-block;
    width: 100px;
    height: 100px;
    border-radius: 5px;
    box-shadow: 2px 2px 5px 2px grey;
}

#avatar:hover {
    cursor: pointer;
}

#avatardiv {
    display: inline-block;
    width: 100px;
    height: 100px;
}

h4.modal-title {
    font-weight: bold;
    margin-left: 5px;
}

#small-description-upload {
    font-size: 18px;
    padding-left: 10px;
    padding-right: 10px;
    padding-bottom: 10px;
    margin-top: 10px;
    margin-bottom: 10px;
    height: 40px;
    width: 450px;
    border-top: 0px;
    border-left: 0px;
    border-right: 0px;
    border-bottom: 2px solid #dbdbdb;
}

#small-description-upload:focus {
    outline: 0;
    border-top: 0px;
    border-left: 0px;
    border-right: 0px;
    transition: border-bottom 500ms ease 0s;
    border-bottom: 2px solid rgb(0,172,194); 
}

input.edit-image-input {
    margin-left: 20px;
    background-color: white;
    border: 1px solid rgb(42, 149, 211);
    border-radius: 3px;
    width: 80px;
    height: 30px;
    color: rgb(42, 149, 211);
}

p.username {
    display: inline-block;
    color: black;
    margin-left: 30px;
    font-size: 35px;
    font-weight: bold;
}

p.small-description {
    cursor: pointer;
    line-height: 40px;
    margin-left: 135px;
    margin-top: -20px;
    font-size: 18px;
    color: rgb(85, 85, 85)
}

hr.line1{
    margin-top: 30px; 
    padding-bottom: 20px;
}

.user-description {
    margin-left: 50px;
    margin-right: 50px;
}

p.user-detail-title {
    font-size: 22px;
    font-weight: bold;
    margin-bottom: 30px;
    color: black
}

button.turn-editor-button {
    background-color: white;
    border: 1px solid rgb(42, 149, 211);
    border-radius: 3px;
    width: 70px;
    height: 30px;
    float: right;
    margin-top: -60px;
    margin-right: 20px;
    font-size: 16px;
    color: rgb(42, 149, 211);
}

button.turn-editor-button:hover, button.turn-editor-button:active {
    background-color: rgb(216, 241, 255);
    outline: 0; 
}

p.user-detail-write-title {
    font-size: 22px;
    font-weight: bold;
    margin-bottom: 20px;
    color: black;
}

.button-wrapper {
    margin-bottom: 20px;
}

button.turn-text-button {
    background-color: white;
    border: 1px solid rgb(42, 149, 211);
    border-radius: 3px;
    width: 60px;
    height: 30px;
    float: right;
    margin-top: -45px;
    margin-right: 20px;
    font-size: 16px;
    color: rgb(42, 149, 211);
}

button.turn-text-button:hover, button.turn-text-button:active {
    background-color: rgb(216, 241, 255);
    outline: 0;
}

button.save-text-button {
    background-color: rgb(199, 4, 4);
    border: 1px solid rgb(199, 4, 4);
    border-radius: 3px;
    width: 60px;
    height: 30px;
    float: right;
    margin-top: -45px;
    margin-right: 95px;
    color: white;
    font-size: 16px;
}

button.save-text-button:hover, button.save-text-button:active {
    background-color: rgb(230, 35, 35);
    outline: 0;
}

#toolbar-container { 
    border-bottom: 1px solid #ccc; 
}

#editor-container { 
    height: 500px; 
    border-bottom: 1px solid #ccc; 
}

hr.line2{
    margin-top: 30px; 
    padding-bottom: 30px;
}

hr.line2-end {
    margin-top: 30px;
    margin-bottom: 80px;
    padding-bottom: 80px;
}

.user-settings {
    margin-left: 50px;
    margin-right: 50px;
}

p.user-settings-title {
    font-size: 22px;
    font-weight: bold;
    margin-bottom: 30px;
    color: black;
}

button.logout-button {
    background-color: rgb(199, 4, 4);
    border: 1px solid rgb(199, 4, 4);
    border-radius: 3px;
    width: 60px;
    height: 30px;
    float: right;
    margin-top: -60px;
    margin-right: 30px;
    color: white;
    font-size: 16px;
}

button.logout-button:hover, button.logout-button:active {
    background-color: rgb(230, 35, 35);
    outline: 0;
}

button.reset-password-button {
    background-color: rgb(199, 4, 4);
    border: 1px solid rgb(199, 4, 4);
    border-radius: 3px;
    width: 95px;
    height: 30px;
    float: right;
    margin-top: -60px;
    margin-right: 115px;
    color: white;
    font-size: 16px;
}

button.reset-password-button:hover, button.reset-password-button:active {
    background-color: rgb(230, 35, 35);
    outline: 0;
}

hr.line3 {
    margin-top: 40px; 
    padding-bottom: 60px;
}

h4.modal-title {
    color: black;
}

/LZLBlog/login/static/login/js/custom.js

$(document).ready(function () {
  $('[data-toggle="tooltip"]').tooltip();
});
  
setTimeout(function () {
  $('.loader_bg').fadeToggle();
}, 1500);

/LZLBlog/login/static/login/js/user_index.js

tinymce.init({
    selector: '#editor-space',
    plugins: 'lists, advlist, anchor, autolink, autosave, charmap, emoticons, fullscreen, link, preview, table, searchreplace, image',
    toolbar: 'undo redo restoredraft  searchreplace| preview | newdocument fullscreen | cut copy paste | lineheight hr | bold italic underline strikethrough subscript superscript forecolor backcolor blockquote | alignleft aligncenter alignright alignjustify | styleselect formatselect fontselect fontsizeselect removeformat | outdent indent | bullist numlist table | anchor link | charmap emoticons image',
    auto_focus: true,
    branding: false,
    elementpath: false,
    promotion: false,
    height: 500,
    placeholder: '在此处输入内容…',
    language: "zh-Hans",
    images_upload_url: '/login/upload_image/',
});

function turn_editor_visible(){
    document.getElementById('editor-wrapper').removeAttribute("style");
    document.getElementById('user-detail-group').style.display = "none";
}

function turn_text_visible(){
    document.getElementById('user-detail-group').removeAttribute("style");
    document.getElementById('editor-wrapper').style.display = "none";
}

function getImg(){
    document.querySelector('#avatar-upload').click();
}

function uploadImg(){
    document.querySelector('#avatar-form').submit();
}

function uploadDescription(){
    document.querySelector('#description-form').submit();
}

var avatar_div = document.getElementById('avatardiv');
var timer = null;
var alpha = 100;
var speed = 1.5;
var avatar_type = 0;
function avatar_mouseover(){
    startChange(avatar_div,speed,30);
}
function avatar_mouseout(){
    startChange(avatar_div,speed,30);
}

function show_SmallDescriptionModal(){
    $('#description-modal').modal('show');
}

function logout(){
    swal({
        title: "确定要登出吗?",
        icon: "warning",
        closeOnClickOutside: true,
        buttons: ['取消', '确定']
    }).then((willLogout) => {
        if (willLogout){
            window.location.href = '/login/logout/';
        }
    });
}

function reset_password(){
    swal({
        title: "确定要修改密码吗?",
        icon: "warning",
        closeOnClickOutside: true,
        buttons: ['取消', '确定']
    }).then((willReset) => {
        if (willReset){
            window.location.href = '/login/reset/';
        }
    });
}

$(document).ready(function(){
    $('[data-toggle="tooltip"]').tooltip();
});

3. 404 页面前端代码

准备工作:

1. 在 /LZLBlog/login/templates/login/ 新建 404.html

2. 在 /LZLBlog/login/static/login/css 新建 404.css

大致结构:

  1. 全屏显示 404.gif

404 页面前端代码:

/LZLBlog/login/templates/login/404.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link href="{% static 'login/css/404.css' %}" rel="stylesheet"/> 
    <link href="{% static 'login/image/favicon.ico' %}" rel="shortcut icon"/>
    <title>(キ`゚Д゚´)!!  页面丢失了!</title>
</head>

<body></body></html>

/LZLBlog/login/static/login/css/404.css

body {
    height: 100%;
    background-image: url('../image/404.gif');
    background-repeat: no-repeat;
    background-attachment: fixed;   
}

4. 总结构图

结构图如下:

本篇的内容到此结束啦~

下篇去做 media 配置 、发送邮件的配置、自定义标签的配置~