Python+Flask+MysqL的web技术建站过程
1.个人学期总结
时间过得飞快,转眼间2017年就要过去。这一年,我学习JSP和Python,哪一门都像一样新的东西,之前从来没有学习过。
这里我就用我学习过的Python和大家分享一下,我是怎么从一具小白到菜鸟到初学者到现在的基本可以运用Python去开发自己的
WEB项目。
回想这一年,我的内心是平静的。觉到自己已经不再不羁,青春已然流逝着,岁月从不饶人。从此开始,不再有不着边际的
想象,不再有异想天开的策划。突然觉得自己长大了很多,从无知到渐渐的成熟。我学到了很多。我明白了宽容别人,明白了什
么叫做真诚。然而这些,我从前仅仅是知道,却不明白。
那我来给大家说一下总结Python+Flask+MysqL的web建设技术。
2.总结Python+Flask+MysqL的web建设技术过程,标准如下:
学习 Flask,写完一个 Flask 应用需要部署的时候,就想着折腾自己的服务器。根据搜索的教程照做,对于原理一知半解,磕
磕碰碰,只要运行起来了,谢天谢地然后不再折腾了,到下一次还需要部署时,这样的过程就会重复一次。不知道多少人的膝盖中
箭了呢?我也这样干过,这么做确实很蠢,所以我决定写一篇 Python+Flask+MysqL+Windows 的部署教程,解答一些我自己在这个过
程中的疑问,从原理到方案,以一个小白的角度,总结一下部署、运维这件事,应该对初学 Flask 需要部署的同学有些帮助。
1.环境的搭建和常用工具简介
下载python3.6(登录官网):https://www.python.org/getit/
下载最新的python版本
下载windows86-64 的基础版,如果是苹果机就下max版
https://www.python.org/ftp/python/3.6.4/python-3.6.4-amd64-webinstall.exe
安装
下载好之后是一个windows可以直接执行的exe程序
点击安装:
注意的是,安装时要点上加入环境变量中,不然之后要自己手动配置环境变量
安装成功之后,怎么检验
win+R键,输入cmd,确定
输入:python
如果有以下的错误的话,就检查一下你的安装路径是否在环境变量之中
成功则显示以下信息:
下载PyCharm(登录官网)
这里有一分PyCharm的介绍:https://baike.baidu.com/item/PyCharm
搭建环境
1、win10_X64,其他Win版本也可以。
2、PyCharm版本:Professional-2016.2.3。
搭建准备
1、到PyCharm官网下载PyCharm安装包。
需要破解版的可以自行百度,这里就不开新的支线,不过我建议还是用正版的,人家开发软件也不容易
2.使用pip进行包管理
1 pip install flask 2 pip install pymysql 3 pip install sqlalchemy 4 pip install flask_sqlalchemy
3.安装数据库及其可视化工具,这里我用的Mysql数据库
由于安装数据库容易出现各种错误,我在这里推荐一款集成开发软件,是我在开发php的时学习到的一款工具,
这样可以免去了安装mysql出现错误带来问题。
安装成功后:桌面会显示这个图表
右键:以管理员的身份来运行
一是开机自动启动,二是WEB服务器已经成功部署
我是安在D盘的,Mysql的地址在PHPStudy中的mysql文件夹之中
还有一个工具叫sqlyog
下载地址:https://sqlyog.en.softonic.com/
安装成功后:
点击新建:
默认是本机的地址:localhost
用户名:root
密码:root
端口:3306
进入后的界面是:
本项目还用到了Bootsrap框架和layui框架,用到了Uedier插件,要自行下载,这里不作说明
4.环境已经搭建好了之后,开始进入正式的建站之路
4.1用pycharm准备一个Flask的项目
打开pycharm,新建一个项目,要先选好python的版本,还有安装存放的地径
这样就打开了一个Flask项目,在编辑区右键,运行我们可看到项目打来的Hello World!
浏览器中输入http://127.0.0.1:5000
导入库在项目的py文件中
1 from flask import Flask, render_template, request, redirect, url_for, session 2 from sqlalchemy import or_ 3 from functools import wraps 4 from hashlib import md5 5 from models import User,Book,Classification,Commentaries 6 from db import db 7 import os,congif
数据库名的设计
mysql创建数据库mis_db
新建一个py文件 confiy.py的文件存放数据库连接信息
1 #encoding: utf-8 2 import os 3 DEBUG = True 4 5 SECRET_KEY = os.urandom(24) 6 7 DIALECT = 'mysql' 8 DRIVER = 'mysqldb' 9 USERNAME = 'root' 10 PASSWORD = 'root' 11 HOST = 'localhost' 12 PORT = '3306' 13 DATABASE = 'mis_db' 14 15 16 SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@localhost:3306/mis_db?charset=utf8' 17 SQLALCHEMY_TRACK_MODIFICATIONS = False
新建一个py文件 db.py的文件存放数据库连接对象和Flask框架
1 from flask_sqlalchemy import SQLAlchemy 2 db = SQLAlchemy()
新建一个py文件 models.py的文件存放数据库表的对象
其中包括了表的表名和列名及其基本信息
1 from db import db 2 3 # 用户信息 4 class User(db.Model): 5 __tablename__ = 'user' 6 id = db.Column(db.String(17), primary_key=True) # 数据库唯识别id 7 name = db.Column(db.String(20), nullable=False) # 登录账号名 8 title = db.Column(db.String(30)) # 显示名称 9 password = db.Column(db.String(42), nullable=False) # 密码 10 truename = db.Column(db.String(10)) # 真实姓名 11 sex = db.Column(db.String(1), default='0') # 性别 12 phone = db.Column(db.String(11)) # 电话号码 13 email = db.Column(db.String(40)) # 邮箱 14 logo = db.Column(db.String(50)) # 头像 15 qq = db.Column(db.String(11)) # qq号码 16 createdate = db.Column(db.DATETIME) # 注册日期 17 level = db.Column(db.String(2)) # 用户等级 18 address = db.Column(db.String(60)) # 用户住址 19 20 # 图书分类 classification(id,name,content) 21 class Classification(db.Model): 22 __tablname__ = 'classification' 23 id = db.Column(db.String(17), primary_key=True) # 数据库唯识别id 24 name = db.Column(db.String(30)) # 文章名称 25 logo = db.Column(db.String(50)) # 头像地址 26 context = db.Column(db.TEXT) # 分类内容 27 28 # 发布图书及问答 29 class Book(db.Model): 30 __tablname__ = 'book' 31 id = db.Column(db.String(17), primary_key=True) # 数据库唯识别id 32 title = db.Column(db.String(30)) # 文章标题 33 abstracts = db.Column(db.String(150)) # 文章摘要 34 content = db.Column(db.TEXT) # 文章内容 35 createdate = db.Column(db.DATETIME) # 发布时间 36 author_id = db.Column(db.String(17), db.ForeignKey('user.id')) # 发布者id 37 size = db.Column(db.String(30)) # 文章长度 38 chilk = db.Column(db.Integer()) # 阅读数 39 disc = db.Column(db.Integer()) #点赞数 40 classification = db.Column(db.String(17), db.ForeignKey('classification.id')) # 文章分类id 41 authorClass = db.relationship('User', backref=db.backref('book')) 42 classificationClass = db.relationship('Classification', backref=db.backref('book')) 43 44 # 评论表 45 class Commentaries(db.Model): 46 __tablname__ = 'commentaries' 47 id = db.Column(db.String(17), primary_key=True) # 数据库唯一识别id 48 book_id = db.Column(db.String(17), db.ForeignKey('book.id')) # 评论对应的文章的id 49 question_id = db.Column(db.String(17)) # 问题的提出者id,或者是文章作者id 50 answer_id = db.Column(db.String(17), db.ForeignKey('user.id')) # 回答问题用户的id 51 date = db.Column(db.DATETIME) # 回答日期 52 content = db.Column(db.TEXT) # 回答内容 53 answer = db.relationship('User', backref=db.backref('commentaries')) 54 book = db.relationship('Book', backref=db.backref('commentaries',order_by=date.desc))
主项目文件中加上这两行
1 app.config.from_object(config) 2 db.init_app(app)
临时在主项目上加上建表的python语句,建表后可以注释了
运行项目,没有错误则可。
可以看到表就稳了
添加触发器一个三个触发器用于生成表的ID
1 DELIMITER $$ 2 3 USE `mis_db`$$ 4 5 DROP TRIGGER /*!50032 IF EXISTS */ `tri_book_id`$$ 6 7 CREATE 8 /*!50017 DEFINER = 'mis'@'%' */ 9 TRIGGER `tri_book_id` BEFORE INSERT ON `book` 10 FOR EACH ROW SET 11 new.id =CONCAT(DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(RAND()*100),3,'0')), 12 new.createdate=DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%s'); 13 $$ 14 15 DELIMITER ;
1 DELIMITER $$ 2 3 USE `mis_db`$$ 4 5 DROP TRIGGER /*!50032 IF EXISTS */ `tri_classification_id`$$ 6 7 CREATE 8 /*!50017 DEFINER = 'mis'@'%' */ 9 TRIGGER `tri_classification_id` BEFORE INSERT ON `classification` 10 FOR EACH ROW SET 11 new.id =CONCAT(DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(RAND()*100),3,'0')); 12 $$ 13 14 DELIMITER ;
1 DELIMITER $$ 2 3 USE `mis_db`$$ 4 5 DROP TRIGGER /*!50032 IF EXISTS */ `tri_commentaries_id`$$ 6 7 CREATE 8 /*!50017 DEFINER = 'mis'@'%' */ 9 TRIGGER `tri_commentaries_id` BEFORE INSERT ON `commentaries` 10 FOR EACH ROW SET 11 new.id =CONCAT(DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(RAND()*100),3,'0')), 12 new.date=DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%s'); 13 $$ 14 15 DELIMITER ;
1 DELIMITER $$ 2 3 USE `mis_db`$$ 4 5 DROP TRIGGER /*!50032 IF EXISTS */ `tri_user_id`$$ 6 7 CREATE 8 /*!50017 DEFINER = 'mis'@'%' */ 9 TRIGGER `tri_user_id` BEFORE INSERT ON `user` 10 FOR EACH ROW SET 11 new.id =CONCAT(DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(RAND()*100),3,'0')), 12 new.createdate=DATE_FORMAT(NOW(),'%Y-%m-%d %H:%i:%s'), 13 new.password=MD5(new.password); 14 $$ 15 16 DELIMITER ;
在sqlyog中分别执行一下上述代码
前期:新建以文件目录(其中Bootsrap、layui、ueditor自行上网下载)
一、准备一套母模板用被继承 命名为( Index.html)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>{% block title %}{% endblock %} -享书</title> 6 <link rel="icon" href="{{ url_for('static',filename='img/logo.ico') }}"> 7 <!--引入CSS文件--> 8 <link rel="stylesheet" href="{{ url_for('static',filename='css/second.css') }}"> 9 <link rel="stylesheet" href="{{ url_for('static',filename='layui/css/layui.css') }}" media="all"> 10 {% block link %}{% endblock %} 11 </head> 12 <body class="box" id="body"> 13 <nav> 14 <div class="layui-row" style="padding-top:8px;"> 15 <div class="layui-col-md8"> 16 <div class="layui-row"> 17 <div class="layui-col-md1"> </div> 18 <div class="layui-col-md11"> 19 <div class="layui-row"> 20 <div class="layui-col-md1"> 21 <a href="{{ url_for('index') }}"> 22 <div class="layui-nav-img"><img src="{{ url_for('static',filename='img/logo.png') }}" 23 alt="logo" width="50px"></div> 24 </a> 25 </div> 26 <div class="layui-col-md3" style="font-size: 25px;padding-top: 5px;"> 27 <span class=""> 28 <a href="{{ url_for('index') }}">首页</a> | 29 <a href="{{ url_for('question') }}">分享你的爱书</a> 30 </span> 31 </div> 32 <div class="layui-col-md8" style="padding-top:3px;"> 33 <form method="get" action="{{ url_for('search') }}"> 34 <div class="layui-row"> 35 <div class="layui-col-md3" style="padding-left: 10px;"> 36 <input type="text" name="q" required lay-verify="required" 37 placeholder="请输入搜索内容" 38 autocomplete="off" class="layui-input"> 39 </div> 40 <div class="layui-col-md3" style="padding-left: 10px;"> 41 <button type="submit" class="layui-btn layui-btn-primary">搜索</button> 42 </div> 43 </div> 44 </form> 45 </div> 46 </div> 47 </div> 48 </div> 49 </div> 50 <div class="layui-col-md4"> 51 <div class="layui-row"> 52 {% if not title %} 53 <div class="layui-col-md4" style="padding-top: 5px;padding-left: 30px;"> 54 <a class="layui-btn layui-btn-small layui-btn-radius layui-btn-primary" 55 href="{{ url_for('login') }}">登录</a> 56 </div> 57 <div class="layui-col-md4"> 58 <a class="layui-btn layui-btn-radius layui-btn-danger" href="{{ url_for('regist') }}">注册</a> 59 </div> 60 {% else %} 61 <div class="layui-col-md4" style="padding-top: 5px;padding-left: 30px;"> 62 <div style="margin-top: -13px; width:140px;"> 63 <ul class="layui-nav layui-bg-withe"> 64 <li class="layui-nav-item"> 65 <a href="javascript:;" style="color: black;">个人中心</a> 66 <dl class="layui-nav-child"> 67 <dd class="dd-item"><a href="{{ url_for('commentaries',user_id=user_id) }}">{{ title }}</a></dd> 68 <dd class="dd-item"><a href="{{ url_for('resetPassword',user_id=user_id) }}">修改密码</a></dd> 69 <dd class="dd-item"><a href="{{ url_for('config',user_id=user_id) }}">设置</a></dd> 70 </dl> 71 </li> 72 </ul> 73 </div> 74 </div> 75 <div class="layui-col-md4"> 76 <a class="layui-btn layui-btn-radius layui-btn-danger" href="{{ url_for('logout') }}">注销</a> 77 </div> 78 {% endif %} 79 80 <div class="layui-col-md4"> 81 <button class="layui-btn layui-btn-radius layui-btn-warm" onclick="light()" type="button" 82 id="light">关灯 83 </button> 84 </div> 85 </div> 86 </div> 87 </div> 88 </nav> 89 <div class="box"> 90 {% block box %}{% endblock %} 91 </div> 92 <footer> 93 <div class="footer_box"> 94 Copyright@ 2017-2022 个人版权,版权所有 作者:叶在林 95 </div> 96 </footer> 97 98 <!--引入js文件--> 99 <script src="{{ url_for('static',filename='js/public.js') }}"></script> 100 <script src="{{ url_for('static',filename='layui/layui.js') }}" charset="utf-8"></script> 101 <script src="{{ url_for('static',filename='js/jquery.js') }}" charset="utf-8"></script> 102 <script src="{{url_for('static',filename='bootstrap/js/bootstrap.min.js')}}"></script> 103 <script> 104 layui.use('element', function () { 105 var element = layui.element; //导航的hover效果、二级菜单等功能,需要依赖element模块 106 107 //监听导航点击 108 element.on('nav(demo)', function (elem) { 109 //console.log(elem) 110 layer.msg(elem.text()); 111 }); 112 }); 113 </script> 114 {% block script %}{% endblock %} 115 </body> 116 </html>
二、注册页
1 {% extends 'index.html' %} 2 {% block title %} 3 注册 4 {% endblock %} 5 6 {% block link %} 7 8 {% endblock %} 9 10 {% block box %} 11 <div class="regis_box regis_box_on" id="box"> 12 <!--css--> 13 <div class=""> 14 <!--头部提示--> 15 <div class="font_title"> 16 注册新用户 17 <hr class=""> 18 </div> 19 <!--表单--> 20 <form class="layui-form" role="form" id="form_regis" method="post" action="{{ url_for('regist') }}" name="form_regis" 21 onSubmit="return registration()"> 22 <!--每一行--> 23 <div class="layui-form-item"> 24 <label class="layui-form-label">登录帐号</label> 25 <div class="layui-input-block"> 26 <input type="text" name="user_name" id="user_name" autocomplete="off" placeholder="登录用户名,不少于6个字符" 27 class="layui-input"> 28 </div> 29 </div> 30 31 <div class="layui-form-item"> 32 <label class="layui-form-label">显示名称</label> 33 <div class="layui-input-block"> 34 <input type="text" name="user_title" autocomplete="off" placeholder="显示名称" class="layui-input"> 35 </div> 36 </div> 37 38 <div class="layui-form-item"> 39 <label class="layui-form-label">密码</label> 40 <div class="layui-input-block"> 41 <input type="password" name="user_password" placeholder="密码6到20位,只能包含字母、数字" autocomplete="off" 42 class="layui-input"> 43 </div> 44 </div> 45 46 <div class="layui-form-item"> 47 <label class="layui-form-label">确认密码</label> 48 <div class="layui-input-block"> 49 <input type="password" name="check_password" placeholder="请输入确认密码" autocomplete="off" 50 class="layui-input"> 51 </div> 52 </div> 53 <div id="error_box" style="color: red;"> 54 <br> 55 </div> 56 <!--注册按钮--> 57 <div class="btn_submit_regis"> 58 <button type="submit" class="layui-btn layui-btn-normal">注册</button> 59 </div> 60 <!--协议提示--> 61 </form> 62 </div> 63 </div> 64 <script> 65 $('#user_name').change(function () { 66 $.get( 67 '{{ url_for('regist') }}', 68 { 69 user_name : $('#user_name').val() 70 }, 71 function (data) { 72 if(data != 'ok') 73 $('#error_box').html(data) 74 } 75 ) 76 }) 77 </script> 78 {% endblock %}
三、登陆页
1 {% extends 'index.html' %} 2 {% block title %} 3 注册 4 {% endblock %} 5 6 {% block link %} 7 8 {% endblock %} 9 10 {% block box %} 11 <div class="regis_box regis_box_on" id="box"> 12 <!--css--> 13 <div class=""> 14 <!--头部提示--> 15 <div class="font_title"> 16 注册新用户 17 <hr class=""> 18 </div> 19 <!--表单--> 20 <form class="layui-form" role="form" id="form_regis" method="post" action="{{ url_for('regist') }}" name="form_regis" 21 onSubmit="return registration()"> 22 <!--每一行--> 23 <div class="layui-form-item"> 24 <label class="layui-form-label">登录帐号</label> 25 <div class="layui-input-block"> 26 <input type="text" name="user_name" id="user_name" autocomplete="off" placeholder="登录用户名,不少于6个字符" 27 class="layui-input"> 28 </div> 29 </div> 30 31 <div class="layui-form-item"> 32 <label class="layui-form-label">显示名称</label> 33 <div class="layui-input-block"> 34 <input type="text" name="user_title" autocomplete="off" placeholder="显示名称" class="layui-input"> 35 </div> 36 </div> 37 38 <div class="layui-form-item"> 39 <label class="layui-form-label">密码</label> 40 <div class="layui-input-block"> 41 <input type="password" name="user_password" placeholder="密码6到20位,只能包含字母、数字" autocomplete="off" 42 class="layui-input"> 43 </div> 44 </div> 45 46 <div class="layui-form-item"> 47 <label class="layui-form-label">确认密码</label> 48 <div class="layui-input-block"> 49 <input type="password" name="check_password" placeholder="请输入确认密码" autocomplete="off" 50 class="layui-input"> 51 </div> 52 </div> 53 <div id="error_box" style="color: red;"> 54 <br> 55 </div> 56 <!--注册按钮--> 57 <div class="btn_submit_regis"> 58 <button type="submit" class="layui-btn layui-btn-normal">注册</button> 59 </div> 60 <!--协议提示--> 61 </form> 62 </div> 63 </div> 64 <script> 65 $('#user_name').change(function () { 66 $.get( 67 '{{ url_for('regist') }}', 68 { 69 user_name : $('#user_name').val() 70 }, 71 function (data) { 72 if(data != 'ok') 73 $('#error_box').html(data) 74 } 75 ) 76 }) 77 </script> 78 {% endblock %}
四、详情页
1 {% extends 'index.html' %} 2 {% block title %} 3 {{ book.title }} 4 {% endblock %} 5 6 {% block link %} 7 <link rel="stylesheet" href="{{ url_for('static', filename='css/poi.css') }}"> 8 <link rel="stylesheet" href="{{ url_for('static', filename='css/home.css') }}"> 9 {% endblock %} 10 11 {% block box %} 12 <div class="context"> 13 <!--左填充--> 14 <div class="index index-left"></div> 15 <!--中间主要内容 --> 16 <div class="index index-center"> 17 <!--轮播图 start--> 18 <div class="picture"> 19 <div class="layui-carousel" id="test1"> 20 <div carousel-item> 21 <div><img src="{{ url_for('static', filename='img/index_p1.png') }}" width="100%"/></div> 22 <div><img src="{{ url_for('static', filename='img/index_p4.png') }}" width="100%"/></div> 23 <div><img src="{{ url_for('static', filename='img/index_p5.png') }}" width="100%"/></div> 24 <div><img src="{{ url_for('static', filename='img/index_p6.png') }}" width="100%"/></div> 25 <div><img src="{{ url_for('static', filename='img/index_p7.png') }}" width="100%"/></div> 26 </div> 27 </div> 28 </div> 29 <!--轮播图 end--> 30 <br><br> 31 <!-- 文章 --> 32 <div class="poi_note"> 33 <div class="poi_post"> 34 <!-- 文章主体信息 --> 35 <div class="poi_article"> 36 <h1 class="poi_title">{{ book.title }}</h1> 37 <!-- 作者区域 --> 38 <div class="poi_author"> 39 <a class="poi_avatar" href="{{ url_for('commentaries',user_id= book.authorClass.id) }}"> 40 <img src="{{ url_for('static',filename=book.authorClass.logo) }}" width="96px"> 41 </a> 42 <div class="poi_info"> 43 <span class="poi_name"><a 44 href="{{ url_for('commentaries',user_id= book.authorClass.id) }}">{{ book.authorClass.title }}</a></span> 45 <!-- 关注用户按钮 --> 46 <a class="layui-btn layui-btn-radius layui-btn-xs"><span>关注</span></a> 47 <!-- 文章数据信息 --> 48 <div class="poi_meta"> 49 <!-- 如果文章更新时间大于发布时间,那么使用 tooltip 显示更新时间 --> 50 <span class="poi_publish-time">{{ book.createdate }}</span> 51 <span class="poi_wordage">字数 {{ book.size }}</span> 52 <span class="poi_views-count">阅读 {{ book.chilk }}</span> 53 <span class="poi_comments-count">评论 {{ answer }}</span> 54 <span class="poi_likes-count">喜欢 {{ book.disc }}</span> 55 <a href="javascript:void (0)" id="on{{ book.id }}" 56 onclick="discBook('{{ book.id }}')"> <i 57 class="layui-icon" 58 style="font-size: 20px;color: #1E9FFF;"></i></a><span 59 id="di{{ book.id }}"> {{ book.disc }}</span> 60 </div> 61 </div> 62 </div> 63 <!-- 文章内容 --> 64 <div class="poi_show-content"> 65 {{ book.content }} 66 </div> 67 <!-- 版权信息 --> 68 <div class="poi_show-foot"> 69 <a class="poi_notebook" 70 href="{{ url_for('classfly',classification_id=book.classificationClass.id) }}"> 71 <i class="iconfont ic-search-notebook"></i> 72 <span>{{ book.classificationClass.name }}</span> 73 </a> 74 <div class="poi_copyright"> 75 © 著作权归作者所有 76 </div> 77 <a href="javascript:void (0)" id="on{{ book.id }}" onclick="discBook('{{ book.id }}')"> <i 78 class="layui-icon" style="font-size: 20px;color: #1E9FFF;"></i></a><span 79 id="di{{ book.id }}"> {{ book.disc }}</span> 80 <div class="poi_modal-wrap" data-report-note=""> 81 <a id="report-modal">举报文章</a> 82 </div> 83 </div> 84 </div> 85 <!-- 文章底部作者信息 --> 86 <div class="poi_follow-detail"> 87 <div class="poi_info" style="width: 100%;"> 88 <a class="poi_avatar" href="{{ url_for('commentaries',user_id= book.authorClass.id) }}"> 89 <img src="{{ url_for('static',filename=book.authorClass.logo) }}" width="64" 90 alt="96"> 91 </a> 92 <a class="layui-btn layui-btn-radius layui-btn-xs right"><span>关注</span></a> 93 <a class="poi_title" 94 href="{{ url_for('commentaries',user_id= book.authorClass.id) }}">{{ book.authorClass.title }}</a> 95 <p style="">写了 138734 字,被 8742 人关注,获得了 15903 个喜欢</p> 96 </div> 97 <div class="poi_signature"> 98 做一个有意思的菇凉,即使老了也是个有意思的老太太。 99 微信公众号:MYmaizi-shuo 微信号:291536040 100 公众号后台回复“必读书籍”免费领取9本电子书。 101 所有文章均为原创,我已委托杭州快板公司对我的文章进行维权,转载开白事宜请加微信,谢谢! 102 </div> 103 </div> 104 </div> 105 </div> 106 <!-- 评论 --> 107 <div class="poi_comment-list"> 108 <!-- 评论区或登录区 --> 109 {% if not title %} 110 <div style="margin-left: 20px;margin-bottom: 50px;"> 111 <form class="new-comment"><a class="avatar" style="position: absolute;left: -48px;"> 112 <img src="{{ url_for('static',filename='img/default_logo.jpg') }}" width="64px"></a> 113 <div class="poi_sign-container"> 114 <a href="{{ url_for('login',poi=book.id) }}" class="layui-btn">登录</a> 115 <span>后发表评论</span> 116 </div> 117 </form> 118 </div> 119 {% else %} 120 <div style="margin-left: 20px;margin-bottom: 50px;"> 121 <form class="new-comment" style="padding-bottom: 30px;"> 122 <a class="avatar" style="position: absolute;left: -48px;"><img 123 src="{{ url_for('static',filename=user.logo) }}" width="64px"></a> 124 <div class="sign-container"> 125 <div class="layui-form-item layui-form-text"> 126 <label class="layui-form-label" for="content">评论内容</label> 127 <div class="layui-input-block"> 128 <div id="content" style="width: 100%;height: 300px;"></div> 129 </div> 130 </div> 131 <!--注册按钮--> 132 <div class="btn_submit_regis"> 133 <button type="button" id="btn_submit_regis" class="layui-btn layui-btn-normal">发布 134 </button> 135 </div> 136 </div> 137 </form> 138 </div> 139 {% endif %} 140 141 <!-- 查看评论区 --> 142 <div class="normal-comment-list"> 143 <div> 144 <div style="margin: 20px;"> 145 <div class="poi_top-title"> 146 <span>{{ answer }}条评论</span> 147 <a class="poi_author-only">只看作者</a> 148 <div class="pull-right"><a class="active">按喜欢排序</a><a class="">按时间正序</a><a 149 class="">按时间倒序</a> 150 </div> 151 </div> 152 </div> 153 <div id="answer"></div> 154 </div> 155 </div> 156 </div> 157 </div> 158 <!--右填充--> 159 <div class="index index-right"></div> 160 </div> 161 {% endblock %} 162 163 {% block script %} 164 <script type="text/javascript" charset="utf-8" 165 src="{{ url_for('static',filename='ueditor/ueditor.config.js') }}"></script> 166 <script type="text/javascript" charset="utf-8" 167 src="{{ url_for('static',filename='ueditor/ueditor.all.min.js') }}"></script> 168 <!--建议手动加在语言,避免在ie下有时因为加载语言失败导致编辑器加载失败--> 169 <!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的中文,那最后就是中文--> 170 <script type="text/javascript" charset="utf-8" 171 src="{{ url_for('static',filename='ueditor/lang/zh-cn/zh-cn.js') }}"></script> 172 <script> 173 //实例化编辑器 174 //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例 175 var ue = UE.getEditor('content', { 176 toolbars: [ 177 ['fullscreen', 'undo', 'redo', 'emotion', 'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', 178 '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc','fontfamily', 'fontsize', 179 ] 180 ], 181 autoHeightEnabled: true, 182 autoFloatEnabled: true 183 }); 184 185 layui.use('carousel', function () { 186 var carousel = layui.carousel; 187 //建造实例 188 carousel.render({ 189 elem: '#test1' 190 , width: '100%' //设置容器宽度 191 , arrow: 'always' //始终显示箭头 192 //,anim: 'updown' //切换动画方式 193 , indicator: 'outside' //窗口内部 194 {# ,full : true // 满屏#} 195 }); 196 }); 197 198 function discBook(id) { 199 $.get( 200 "{{ url_for('disc') }}", 201 { 202 book_id: id 203 }, 204 function (data) { 205 $('#di' + id).html(' ' + data) 206 $('#on' + id).attr('onclick', '') 207 } 208 ) 209 } 210 211 $(function () { 212 $.get( 213 '{{ url_for('answer') }}', 214 { 215 book_id: '{{ book.id }}' 216 }, 217 function (data) { 218 $('#answer').html(data) 219 $('.poi_comment-wrap p').each(function (i, e) { 220 $(this).html(HTMLDecode($(this).html())) 221 }) 222 } 223 ) 224 }) 225 $('#btn_submit_regis').click(function () { 226 $.post( 227 '{{ url_for('answer') }}', 228 { 229 content: ue.getContent(), 230 book_id: '{{ book.id }}', 231 question_id: '{{ book.authorClass.id }}', 232 answer_id: '{{ user.id }}' 233 }, 234 function (data) { 235 ue.execCommand('cleardoc'); 236 $('#answer').html(data) 237 $('.poi_comment-wrap p').each(function (i, e) { 238 $(this).html(HTMLDecode($(this).html())) 239 }) 240 } 241 ) 242 }) 243 244 function HTMLDecode(text) { 245 var temp = document.createElement("div"); 246 temp.innerHTML = text; 247 var output = temp.innerText || temp.textContent; 248 temp = null; 249 return output; 250 } 251 252 $('.poi_show-content').html(HTMLDecode($('.poi_show-content').html())) 253 </script> 254 {% endblock %}
五、发布页
1 {% extends 'index.html' %} 2 {% block title %} 3 发布问答 4 {% endblock %} 5 6 {% block link %} 7 <link rel="stylesheet" href="{{ url_for('static',filename='css/posted.css') }}"> 8 <script type="text/javascript" charset="utf-8" 9 src="{{ url_for('static',filename='ueditor/ueditor.config.js') }}"></script> 10 <script type="text/javascript" charset="utf-8" 11 src="{{ url_for('static',filename='ueditor/ueditor.all.min.js') }}"></script> 12 <!--建议手动加在语言,避免在ie下有时因为加载语言失败导致编辑器加载失败--> 13 <!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的中文,那最后就是中文--> 14 <script type="text/javascript" charset="utf-8" 15 src="{{ url_for('static',filename='ueditor/lang/zh-cn/zh-cn.js') }}"></script> 16 {% endblock %} 17 18 {% block box %} 19 <div style="padding-top: 58px;"> 20 <div class="layui-row layui-col-space5"> 21 <div class="layui-col-md12" style="height: 100px;"> </div> 22 <div class="layui-col-md12"> 23 <div class="layui-row"> 24 <div class="layui-col-md2"> </div> 25 <div class="layui-col-md8"> 26 <div class="posted_box"> 27 <form class="layui-form" role="form" id="form_regis" method="post" action=" #" 28 name="form_regis" 29 onSubmit="return check_posted()"> 30 <div class="layui-form-item"> 31 <label class="layui-form-label" for="title">标题</label> 32 <div class="layui-input-block"> 33 <input type="text" name="user_id" value="{{ user_id }}" hidden> 34 <input type="text" name="title" id="title" autocomplete="off" 35 placeholder="请输入要发布的标题" 36 class="layui-input" required> 37 </div> 38 </div> 39 <div class="layui-form-item layui-form-text"> 40 <label class="layui-form-label" for="content">内容</label> 41 <div class="layui-input-block"> 42 <textarea name="content" id="content" type="text/plain" 43 style="width:100%;height:500px;"></textarea> 44 </div> 45 </div> 46 <div class="layui-form-item"> 47 <label class="layui-form-label">文章分类</label> 48 <div class="layui-input-block"> 49 <select name="classification" lay-filter="aihao" id="classification"> 50 <option value="">--请选择文章分类--</option> 51 {% for cl in classfly %} 52 <option value="{{ cl.id }}">{{ cl.name }}</option> 53 {% endfor %} 54 </select> 55 </div> 56 </div> 57 <!--注册按钮--> 58 <div class="btn_submit_regis"> 59 <button type="button" onclick="submitQuestion()" class="layui-btn layui-btn-normal"> 60 发布 61 </button> 62 </div> 63 </form> 64 </div> 65 </div> 66 <div class="layui-col-md2"> </div> 67 </div> 68 </div> 69 <div class="layui-col-md12" style="height: 200px;"> </div> 70 </div> 71 </div> 72 {% endblock %} 73 74 {% block script %} 75 <script> 76 //实例化编辑器 77 //建议使用工厂方法getEditor创建和引用编辑器实例,如果在某个闭包下引用该编辑器,直接调用UE.getEditor('editor')就能拿到相关的实例 78 var ue = UE.getEditor('content'); 79 80 function submitQuestion() { 81 var classification = document.getElementById('classification') 82 if (classification.value == '') { 83 alert('请选择文章分类!') 84 return false; 85 } 86 $.post( 87 '{{ url_for("question") }}', 88 { 89 'title': document.getElementById('title').value, 90 'content': ue.getContent(), 91 'abstracts': ue.getPlainTxt(), 92 'classification': document.getElementById('classification').value, 93 'user_id': '{{ user_id }}', 94 'size': ue.getContentLength() 95 }, function (data) { 96 if (data == 'true') 97 $(location).prop('href', '{{ url_for('index') }}') 98 } 99 ); 100 } 101 102 layui.use(['form'], function () { 103 var form = layui.form 104 , layer = layui.layer 105 , layedit = layui.layedit 106 , laydate = layui.laydate; 107 }) 108 </script> 109 {% endblock %}
六、修改密码页
七、主页
八、分类列表页
1 {% extends 'index.html' %} 2 {% block title %} 3 首页 4 {% endblock %} 5 6 {% block link %} 7 <link rel="stylesheet" href="{{ url_for('static', filename='css/home.css') }}"> 8 <link rel="stylesheet" href="{{ url_for('static', filename='css/classflyList.css') }}"> 9 {% endblock %} 10 11 {% block box %} 12 <div class="context"> 13 <div class="index index-left"></div> 14 <div class="index index-center" style="background-color: white;padding: 20px;"> 15 <div class="picture"> 16 <div class="layui-carousel" id="test1"> 17 <div carousel-item> 18 <div><img src="{{ url_for('static', filename='img/index_p1.png') }}" width="100%"/></div> 19 <div><img src="{{ url_for('static', filename='img/index_p4.png') }}" width="100%"/></div> 20 <div><img src="{{ url_for('static', filename='img/index_p5.png') }}" width="100%"/></div> 21 <div><img src="{{ url_for('static', filename='img/index_p6.png') }}" width="100%"/></div> 22 <div><img src="{{ url_for('static', filename='img/index_p7.png') }}" width="100%"/></div> 23 </div> 24 </div> 25 </div> 26 <br><br> 27 <div class="index-question" \> 28 <div class="row" id="list-container"> 29 {% for cl in classfly %} 30 <div class="col-xs-8"> 31 <div class="collection-wrap"> 32 <a href="{{ url_for('classfly',classification_id=cl.id) }}"> 33 <img class="avatar-collection" src="{{ url_for('static',filename=cl.logo) }}" 34 alt="180"> 35 <h4 class="avatar-name">{{ cl.name }}</h4> 36 <p class="collection-description">{{ cl.context }}</p> 37 </a> 38 <a class="layui-btn layui-btn-radius" 39 href="{{ url_for('classfly',classification_id=cl.id) }}"> 40 <i class="layui-icon"></i><span>参观</span> 41 </a> 42 <hr> 43 </div> 44 </div> 45 {% endfor %} 46 </div> 47 </div> 48 </div> 49 </div> 50 {% endblock %} 51 52 {% block script %} 53 <script> 54 layui.use('carousel', function () { 55 var carousel = layui.carousel; 56 //建造实例 57 carousel.render({ 58 elem: '#test1' 59 , width: '100%' //设置容器宽度 60 , arrow: 'always' //始终显示箭头 61 //,anim: 'updown' //切换动画方式 62 , indicator: 'outside' //窗口内部 63 {# ,full : true // 满屏#} 64 }); 65 }); 66 </script> 67 {% endblock %}
九、回答页
1 <!-- 评论列表 --> 2 {% for comment in commentaries %} 3 <div class="poi_comment"> 4 <div class="poi_comment_item"> 5 <div class="poi_author"> 6 <div style="z-index: 0;display: inline-block;"> 7 <div class="v-tooltip-content"> 8 <a href="{{ url_for('commentaries',user_id= comment.answer.id) }}" target="_blank" class="poi_avatar"> 9 <img src="{{ url_for('static',filename=comment.answer.logo) }}" width="64px"> 10 </a> 11 </div> 12 </div> 13 <div class="poi_info"> 14 <a href="{{ url_for('commentaries',user_id= comment.answer.id) }}" target="_blank" class="poi_name">{{ comment.answer.title }}</a> 15 <div class="poi_meta"><span>3楼 · {{ comment.date }}</span></div> 16 </div> 17 </div> 18 <div class="poi_comment-wrap"><p>{{ comment.content }}</p> 19 <div class="poi_tool-group"> 20 <a class="#"><span>13人赞 </span></a> 21 <a class="#"><span>回复</span></a> 22 </div> 23 </div> 24 </div> 25 </div> 26 {% endfor %}
十、个人中心
1 {% extends 'index.html' %} 2 {% block title %} 3 个人中心 4 {# {{ book.title }}#} 5 {% endblock %} 6 7 {% block link %} 8 <link rel="stylesheet" href="{{ url_for('static', filename='css/poi.css') }}"> 9 <link rel="stylesheet" href="{{ url_for('static', filename='css/home.css') }}"> 10 {# <!--link rel="stylesheet" href="{{url_for('static',filename='bootstrap/css/bootstrap.min.css')}}"-->#} 11 {% endblock %} 12 13 {% block box %} 14 <div class="context"> 15 <!--左填充--> 16 <div class="index index-left"></div> 17 <!--中间主要内容 --> 18 <div class="index index-center"> 19 <!--轮播图 start--> 20 <div class="picture"> 21 <div class="layui-carousel" id="test1"> 22 <div carousel-item> 23 <div><img src="{{ url_for('static', filename='img/index_p1.png') }}" width="100%"/></div> 24 <div><img src="{{ url_for('static', filename='img/index_p4.png') }}" width="100%"/></div> 25 <div><img src="{{ url_for('static', filename='img/index_p5.png') }}" width="100%"/></div> 26 <div><img src="{{ url_for('static', filename='img/index_p6.png') }}" width="100%"/></div> 27 <div><img src="{{ url_for('static', filename='img/index_p7.png') }}" width="100%"/></div> 28 </div> 29 </div> 30 </div> 31 <!--轮播图 end--> 32 <div class="layui-tab layui-tab-card" style="margin-top: 40px;"> 33 <ul class="layui-tab-title"> 34 <li class="layui-this">评论</li> 35 <li>文章</li> 36 <li>个人信息</li> 37 </ul> 38 <div class="layui-tab-content"> 39 <!-- 评论的列表 --> 40 <div class="layui-tab-item layui-show"> 41 <!-- 查看评论区 --> 42 <div class="normal-comment-list" style="background-color: white;padding: 10px;"> 43 <div> 44 <div style="margin: 20px;"> 45 <div class="poi_top-title"> 46 <span>{{ num }}条评论</span> 47 <a class="poi_author-only">只看作者</a> 48 <div class="pull-right"><a class="active">按喜欢排序</a><a class="">按时间正序</a><a 49 class="">按时间倒序</a> 50 </div> 51 </div> 52 </div> 53 <div id="answer"> 54 <!-- 评论列表 --> 55 {% for comment in userCommentaries %} 56 <div class="poi_comment"> 57 <div class="poi_comment_item"> 58 <div class="poi_author"> 59 <div style="z-index: 0;display: inline-block;"> 60 <div class="v-tooltip-content"> 61 <a href="{{ url_for('commentaries',user_id= comment.answer.id) }}" 62 target="_blank" class="poi_avatar"> 63 <img src="{{ url_for('static',filename=comment.answer.logo) }}"> 64 </a> 65 </div> 66 </div> 67 <div class="poi_info"> 68 <a href="{{ url_for('commentaries',user_id= comment.answer.id) }}" 69 target="_blank" 70 class="poi_name">{{ comment.answer.title }}</a> 71 <div class="poi_meta"><span>1楼 · {{ comment.date }}</span></div> 72 </div> 73 </div> 74 <div class="poi_comment-wrap"><p>{{ comment.content }}</p> 75 <div class="poi_tool-group"> 76 <a class="#"><span>13人赞 </span></a> 77 <a class="#"><span>回复</span></a> 78 </div> 79 </div> 80 </div> 81 </div> 82 {% endfor %} 83 </div> 84 </div> 85 </div> 86 </div> 87 <!-- 文章的列表 --> 88 <div class="layui-tab-item"> 89 <div class="book_list"> 90 {% for book in books %} 91 <li> 92 <div class="item-one"> 93 <div class="author"> 94 <a class="avatar" target="_blank" 95 href="{{ url_for('commentaries',user_id= book.authorClass.id) }}"> 96 <img src="{{ url_for('static',filename=book.authorClass.logo) }}" 97 width="64px;"> 98 </a> 99 <div class="info"> 100 <a class="nickname" target="_blank" 101 href="{{ url_for('commentaries',user_id= book.authorClass.id) }}">{{ book.authorClass.title }}</a> 102 <span class="time">{{ book.createdate }}</span> 103 </div> 104 </div> 105 <div class="title"> 106 <a target="_blank" 107 href="{{ url_for('poi',book_id=book.id) }}">{{ book.title }}</a> 108 </div> 109 <div class="abstract"> 110 <p> 111 {{ book.abstracts }} 112 </p> 113 </div> 114 <div class="meta"> 115 <a class="collection-tag" 116 href="{{ url_for('classfly',classification_id=book.classificationClass.id) }}">{{ book.classificationClass.name }}</a> 117 <a href="{{ url_for('poi',book_id=book.id) }}"><span> 浏览: {{ book.chilk }}</span></a> 118 <a href="{{ url_for('poi',book_id=book.id) }}"><span> 评论: {{ book.commentaries|length }}</span></a> 119 <a href="javascript:void (0)" id="on{{ book.id }}" 120 onclick="discBook('{{ book.id }}')"> <i 121 class="layui-icon" 122 style="font-size: 20px;color: #1E9FFF;"></i></a><span 123 id="di{{ book.id }}"> {{ book.disc }}</span> 124 </div> 125 </div> 126 </li> 127 {% endfor %} 128 </div> 129 </div> 130 <!-- 个人信息 --> 131 <div class="layui-tab-item"> 132 <div style="background-color: #FFFFFF;"> 133 <div class="layui-container"> 134 <div class="layui-row"> 135 <div class="layui-col-md2"> </div> 136 <div class="layui-col-md8"> 137 <form class="layui-form" action=""> 138 <div class="layui-form-item"> 139 <label class="layui-form-label">名称:</label> 140 <div class="layui-input-block" style="padding-top:10px; "> 141 <strong>{{ user2.title }}</strong> 142 </div> 143 </div> 144 <div class="layui-form-item"> 145 <label class="layui-form-label">评论数:</label> 146 <div class="layui-input-block" style="padding-top:10px; "> 147 <strong>{{ userCommentaries|length }}</strong> 148 </div> 149 </div> 150 <div class="layui-form-item"> 151 <label class="layui-form-label">文章数:</label> 152 <div class="layui-input-block" style="padding-top:10px; "> 153 <strong>{{ books|length }}</strong> 154 </div> 155 </div> 156 </form> 157 </div> 158 <div class="layui-col-md2"> </div> 159 </div> 160 </div> 161 </div> 162 </div> 163 </div> 164 </div> 165 166 </div> 167 </div> 168 <!--右填充--> 169 <div class="index index-right"></div> 170 </div> 171 {% endblock %} 172 173 {% block script %} 174 <script> 175 176 $('.poi_comment-wrap p').each(function (i, e) { 177 $(this).html(HTMLDecode($(this).html())) 178 }) 179 180 function discBook(id) { 181 $.get( 182 "{{ url_for('disc') }}", 183 { 184 book_id: id 185 }, 186 function (data) { 187 $('#di' + id).html(' ' + data) 188 $('#on' + id).attr('onclick', '') 189 } 190 ) 191 } 192 193 layui.use('carousel', function () { 194 var carousel = layui.carousel; 195 //建造实例 196 carousel.render({ 197 elem: '#test1' 198 , width: '100%' //设置容器宽度 199 , arrow: 'always' //始终显示箭头 200 //,anim: 'updown' //切换动画方式 201 , indicator: 'outside' //窗口内部 202 {# ,full : true // 满屏#} 203 }); 204 }); 205 </script> 206 {% endblock %}
十一、设置页
1 {% extends 'index.html' %} 2 {% block title %} 3 设置中心 4 {% endblock %} 5 6 {% block link %} 7 <style> 8 .strong { 9 padding-top: 9px; 10 } 11 </style> 12 {% endblock %} 13 14 {% block box %} 15 <div class="layui-row"> 16 <div class="layui-col-md3"> </div> 17 <div class="layui-col-md6" 18 style="padding-top: 30px;padding-right: 60px; background-color: white;min-height: 900px;"> 19 <form class="layui-form" action="{{ url_for('config',user_id=user.id) }}" method="post"> 20 <div class="layui-form-item"> 21 <label class="layui-form-label">账号</label> 22 <div class="layui-input-block strong"> 23 <strong>{{ user.name }}</strong> 24 </div> 25 </div> 26 <div class="layui-form-item"> 27 <label class="layui-form-label">头像</label> 28 <div class="layui-input-block"> 29 <button type="button" class="layui-btn" id="test1"> 30 <i class="layui-icon"></i>上传图片 31 </button> 32 {% if user.logo %} 33 <img style="margin-left: 30px;" src="{{ url_for('static',filename=user.logo) }}" width="64px" alt="" id="logoFile"> 34 {% else %} 35 <img style="margin-left: 30px;" src="{{ url_for('static',filename='img/default_logo.jpg') }}" width="64px" alt="" id="logoFile"> 36 {% endif %} 37 </div> 38 </div> 39 <div class="layui-form-item"> 40 <label class="layui-form-label">名称</label> 41 <div class="layui-input-block"> 42 <input type="text" name="title" value="{{ user.title }}" placeholder="请输入名称" 43 autocomplete="off" class="layui-input"> 44 </div> 45 </div> 46 <div class="layui-form-item"> 47 <label class="layui-form-label">真实姓名</label> 48 <div class="layui-input-block"> 49 <input type="text" name="truename" value="{{ user.truename }}" placeholder="请输入真实姓名" 50 autocomplete="off" class="layui-input"> 51 </div> 52 </div> 53 <div class="layui-form-item"> 54 <label class="layui-form-label">性别</label> 55 <div class="layui-input-block"> 56 <select name="sex" lay-filter="aihao"> 57 <option value="" {% if user.sex == '' %}selected{% endif %}>--请选择性别--</option> 58 <option value="0" {% if user.sex == '0' %}selected{% endif %}>男</option> 59 <option value="1" {% if user.sex == '1' %}selected{% endif %}>女</option> 60 </select> 61 </div> 62 </div> 63 <div class="layui-form-item"> 64 <label class="layui-form-label">QQ</label> 65 <div class="layui-input-block"> 66 <input type="text" name="qq" value="{{ user.qq }}" placeholder="请输入QQ" 67 autocomplete="off" class="layui-input"> 68 </div> 69 </div> 70 <div class="layui-form-item"> 71 <label class="layui-form-label">电话</label> 72 <div class="layui-input-block"> 73 <input type="text" name="phone" value="{{ user.phone }}" placeholder="请输入电话" 74 autocomplete="off" class="layui-input"> 75 </div> 76 </div> 77 <div class="layui-form-item"> 78 <label class="layui-form-label">邮箱</label> 79 <div class="layui-input-block"> 80 <input type="text" name="email" value="{{ user.email }}" placeholder="请输入邮箱" 81 autocomplete="off" class="layui-input"> 82 </div> 83 </div> 84 <div class="layui-form-item"> 85 <label class="layui-form-label">地址</label> 86 <div class="layui-input-block"> 87 <input type="text" name="address" value="{{ user.address }}" placeholder="请输入地址" 88 autocomplete="off" class="layui-input"> 89 </div> 90 </div> 91 <div class="layui-form-item"> 92 <div class="layui-input-block"> 93 <button type="submit" class="layui-btn layui-btn-normal">保存</button> 94 </div> 95 </div> 96 </form> 97 </div> 98 <div class="layui-col-md3"> </div> 99 </div> 100 {% endblock %} 101 102 {% block script %} 103 <script> 104 layui.use(['form', 'upload'], function () { 105 var form = layui.form 106 , layer = layui.layer 107 , layedit = layui.layedit 108 , laydate = layui.laydate; 109 110 var upload = layui.upload; 111 var id = '{{ user.id }}'; 112 //头像上传执行实例 113 var uploadInst = upload.render({ 114 elem: '#test1' //绑定元素 115 , url: '/uploadLogo/'+ id//上传接口 116 ,size:1024 // 最大可上传1Mb 117 ,field:'logo' 118 ,accept:'images' //可上传类型 119 , done: function (res) { 120 //上传完毕回调 121 $('#logoFile').attr('src',res.url); 122 } 123 , error: function () { 124 //请求异常回调 125 } 126 }); 127 }); 128 </script> 129 {% endblock %}
十二、分类文章列表页
1 {% extends 'index.html' %} 2 {% block title %} 3 {{ classfly.name }} 4 {% endblock %} 5 6 {% block link %} 7 <link rel="stylesheet" href="{{ url_for('static', filename='css/home.css') }}"> 8 {% endblock %} 9 10 {% block box %} 11 <div class="context"> 12 <div class="index index-left"></div> 13 <div class="index index-center"> 14 <div class="picture"> 15 <div class="layui-carousel" id="test1"> 16 <div carousel-item> 17 <div><img src="{{ url_for('static', filename='img/index_p1.png') }}" width="100%"/></div> 18 <div><img src="{{ url_for('static', filename='img/index_p4.png') }}" width="100%"/></div> 19 <div><img src="{{ url_for('static', filename='img/index_p5.png') }}" width="100%"/></div> 20 <div><img src="{{ url_for('static', filename='img/index_p6.png') }}" width="100%"/></div> 21 <div><img src="{{ url_for('static', filename='img/index_p7.png') }}" width="100%"/></div> 22 </div> 23 </div> 24 25 </div> 26 <br><br> 27 <div class="index-question"> 28 <div class="recommend-collection"> 29 {% for cl in classflyList %} 30 <a class="collection" href="{{ url_for('classfly',classification_id=cl.id) }}"> 31 <img src="{{ url_for('static',filename=cl.logo) }}" alt="64"> 32 <div class="name">{{ cl.name }}</div> 33 </a> 34 {% endfor %} 35 <a class="more-hot-collection" href="{{ url_for('classflyList') }}">更多热门专题 <i 36 class="iconfont ic-link"></i> 37 </a> 38 </div> 39 <div class="question-left"> 40 <ul> 41 {% for book in books %} 42 <li> 43 <div class="item-one"> 44 <div class="author"> 45 <a class="avatar" 46 href="{{ url_for('commentaries',user_id= book.authorClass.id) }}"> 47 <img src="{{ url_for('static',filename=book.authorClass.logo) }}" 48 width="64px;"> 49 </a> 50 <div class="info"> 51 <a class="nickname" 52 href="{{ url_for('commentaries',user_id= book.authorClass.id) }}">{{ book.authorClass.title }}</a> 53 <span class="time">{{ book.createdate }}</span> 54 </div> 55 </div> 56 <div class="title"> 57 <a href="{{ url_for('poi',book_id=book.id) }}">{{ book.title }}</a> 58 </div> 59 <div class="abstract"> 60 <p> 61 {{ book.abstracts }} 62 </p> 63 </div> 64 <div class="meta"> 65 <a class="collection-tag" 66 href="{{ url_for('classfly',classification_id=book.classificationClass.id) }}">{{ book.classificationClass.name }}</a> 67 <a href="{{ url_for('poi',book_id=book.id) }}"><span> 浏览: {{ book.chilk }}</span></a> 68 <a href="{{ url_for('poi',book_id=book.id) }}"><span> 评论: {{ book.commentaries|length }}</span></a> 69 <a href="javascript:void (0)" id="on{{ book.id }}" 70 onclick="discBook('{{ book.id }}')"> <i 71 class="layui-icon" style="font-size: 20px;color: #1E9FFF;"></i></a><span 72 id="di{{ book.id }}"> {{ book.disc }}</span> 73 </div> 74 </div> 75 </li> 76 {% endfor %} 77 </ul> 78 </div> 79 <div class="question-right"> 80 <div class="picture"> 81 <img src="{{ url_for('static', filename='img/index_p2.png') }}" width="100%"/> 82 </div> 83 <div class="picture"> 84 <img src="{{ url_for('static', filename='img/index_p3.png') }}" width="100%"/> 85 </div> 86 </div> 87 </div> 88 </div> 89 <div class="index index-right"></div> 90 </div> 91 {% endblock %} 92 93 {% block script %} 94 <script> 95 $(function () { 96 $('.abstract').html($(this).html().substr(0, 150)) 97 }) 98 99 function discBook(id) { 100 $.get( 101 "{{ url_for('disc') }}", 102 { 103 book_id: id 104 }, 105 function (data) { 106 $('#di' + id).html(' ' + data) 107 $('#on' + id).attr('onclick', '') 108 } 109 ) 110 } 111 112 layui.use('carousel', function () { 113 var carousel = layui.carousel; 114 //建造实例 115 carousel.render({ 116 elem: '#test1' 117 , width: '100%' //设置容器宽度 118 , arrow: 'always' //始终显示箭头 119 //,anim: 'updown' //切换动画方式 120 , indicator: 'outside' //窗口内部 121 {# ,full : true // 满屏#} 122 }); 123 }); 124 </script> 125 {% endblock %}
JS代码,新建一个public.js文件
1 function validate() { 2 var oError = document.getElementById('error_box'); 3 oError.innerHTML = ""; 4 if (theForm.user_name.value == "") { 5 alert("请输入用户名!"); 6 theForm.user_name.focus() 7 return false; 8 } else { 9 if (theForm.user_name.value.length < 6 || theForm.user_name.value.length > 20) { 10 oError.innerHTML = '用户名请在6到20位之间'; 11 return false; 12 } else if ((theForm.user_name.value.charCodeAt(0) >= 48) && (theForm.user_name.value.charCodeAt(0) <= 57)) { 13 oError.innerHTML = '首字母不可为数字'; 14 return false; 15 } else for (var i = 0; i < theForm.user_name.value.length; i++) { 16 if ( 17 ((theForm.user_name.value.charCodeAt(i) < 48) || (theForm.user_name.value.charCodeAt(i) > 57)) 18 && 19 ((theForm.user_name.value.charCodeAt(i) < 97) || (theForm.user_name.value.charCodeAt(i) > 122)) 20 ) { 21 oError.innerHTML = '用户名只能包含数字和小写字母'; 22 return false; 23 } 24 } 25 } 26 if (theForm.user_password.value == "") { 27 alert("请输入密码!"); 28 theForm.user_password.focus(); 29 return false; 30 } else { 31 if (theForm.user_password.value.length < 6 || theForm.user_password.value.length > 20) { 32 oError.innerHTML = '密码请在6到20位之间'; 33 return false; 34 } 35 } 36 return true; 37 } 38 39 function registration() { 40 var oError = document.getElementById('error_box'); 41 oError.innerHTML = "<br>"; 42 if (form_regis.user_name.value.length < 6 || form_regis.user_name.value.length > 20) { 43 oError.innerHTML = '用户名请在6到20位之间'; 44 return false; 45 } else if ((form_regis.user_name.value.charCodeAt(0) >= 48) && (form_regis.user_name.value.charCodeAt(0) <= 57)) { 46 oError.innerHTML = '首字母不可为数字'; 47 return false; 48 } else for (var i = 0; i < form_regis.user_name.value.length; i++) { 49 if ( 50 ((form_regis.user_name.value.charCodeAt(i) < 48) || (form_regis.user_name.value.charCodeAt(i) > 57)) 51 && 52 ((form_regis.user_name.value.charCodeAt(i) < 97) || (form_regis.user_name.value.charCodeAt(i) > 122)) 53 ) { 54 oError.innerHTML = '用户名只能包含数字和小写字母'; 55 return false; 56 } 57 } 58 59 if (form_regis.user_password.value.length < 6 || form_regis.user_password.value.length > 20) { 60 oError.innerHTML = '密码请在6到20位之间'; 61 return false; 62 } else if (form_regis.user_password.value != form_regis.check_password.value) { 63 oError.innerHTML = '两次密码不一样'; 64 return false; 65 } 66 return true; 67 } 68 69 function light() { 70 var light = document.getElementById('light'); 71 var switch_ = document.getElementById('body'); 72 var box = document.getElementById('box'); 73 if (light.innerHTML == '关灯') { 74 light.className = "layui-btn layui-btn-radius layui-btn-primary"; 75 light.innerHTML = '开灯' 76 switch_.className = "off" 77 box.className = "regis_box regis_box_off" 78 } else { 79 light.className = "layui-btn layui-btn-radius layui-btn-warm"; 80 light.innerHTML = '关灯' 81 switch_.className = "on" 82 box.className = "regis_box regis_box_on" 83 } 84 } 85 86 function resetPassword() { 87 var password = document.getElementById('password').value; 88 var password1 = document.getElementById('password1').value; 89 if(password!= password1){ 90 alert('两次密码不一样'); 91 return false; 92 } 93 }
css代码
1.新建一个classflyList.css文件
1 .row { 2 margin-left: -15px; 3 margin-right: -15px; 4 } 5 6 .col-xs-8 { 7 width: 30%; 8 float: left; 9 position: relative; 10 min-height: 1px; 11 padding-left: 15px; 12 padding-right: 15px; 13 text-align: center; 14 } 15 16 .collection-wrap { 17 height: 280px; 18 margin-top: 80px; 19 padding: 0 20px; 20 border: 1px solid #e6e6e6; 21 border-radius: 4px; 22 background-color: hsla(0, 0%, 71%, .1); 23 transition: .2s ease; 24 -webkit-transition: .2s ease; 25 } 26 27 .avatar-collection { 28 width: 80px; 29 height: 80px; 30 margin: -40px 0 10px; 31 display: inline-block; 32 border: 1px solid #ddd; 33 background-color: #fff; 34 border-radius: 8px; 35 } 36 37 .avatar-name { 38 display: block; 39 -webkit-margin-before: 1.33em; 40 -webkit-margin-after: 1.33em; 41 -webkit-margin-start: 0px; 42 -webkit-margin-end: 0px; 43 font-size: 23px; 44 font-weight: bold; 45 } 46 47 .collection-description { 48 min-height: 55px; 49 font-size: 13px; 50 line-height: 25px; 51 margin: 0 0 10px; 52 }
2.新建一个home.css文件
1 .row { 2 margin-left: -15px; 3 margin-right: -15px; 4 } 5 6 .col-xs-8 { 7 width: 30%; 8 float: left; 9 position: relative; 10 min-height: 1px; 11 padding-left: 15px; 12 padding-right: 15px; 13 text-align: center; 14 } 15 16 .collection-wrap { 17 height: 280px; 18 margin-top: 80px; 19 padding: 0 20px; 20 border: 1px solid #e6e6e6; 21 border-radius: 4px; 22 background-color: hsla(0, 0%, 71%, .1); 23 transition: .2s ease; 24 -webkit-transition: .2s ease; 25 } 26 27 .avatar-collection { 28 width: 80px; 29 height: 80px; 30 margin: -40px 0 10px; 31 display: inline-block; 32 border: 1px solid #ddd; 33 background-color: #fff; 34 border-radius: 8px; 35 } 36 37 .avatar-name { 38 display: block; 39 -webkit-margin-before: 1.33em; 40 -webkit-margin-after: 1.33em; 41 -webkit-margin-start: 0px; 42 -webkit-margin-end: 0px; 43 font-size: 23px; 44 font-weight: bold; 45 } 46 47 .collection-description { 48 min-height: 55px; 49 font-size: 13px; 50 line-height: 25px; 51 margin: 0 0 10px; 52 }
3.新建一个one.css文件
1 html{ 2 height:100%; 3 overflow:hidden; 4 } 5 .login-body{ 6 width:100%; 7 height:100%; 8 background:#56ABF8 url(../img/header_bg.png) no-repeat scroll center center / cover; 9 position:relative; 10 } 11 form { 12 margin: 0px; 13 padding: 0px; 14 } 15 body { 16 margin: 0px; 17 padding: 0px; 18 color: #192E32; 19 font: 12px Microsoft Yahei, "sans-serif", "Arial", "Verdana"; 20 } 21 p, td, div { 22 font: 12px Microsoft Yahei, "sans-serif", "Arial", "Verdana"; 23 } 24 25 th { 26 font: 12px Microsoft Yahei, "sans-serif", "Arial", "Verdana"; 27 font-weight: bold; 28 } 29 input, textarea, select, button { 30 font: 12px Microsoft Yahei, "courier new"; 31 } 32 33 input,textarea{ 34 outline: 0; 35 } 36 37 a:visited { 38 color: #335B64; 39 text-decoration: none; 40 } 41 42 a:link { 43 color: #335B64; 44 text-decoration: none; 45 } 46 47 a:hover { 48 color: #EB8A3D; 49 text-decoration: underline; 50 } 51 52 a:active { 53 color: #EB8A3D; 54 text-decoration: underline; 55 } 56 .login-hd{ 57 background:transparent none repeat scroll 0% 0%; 58 height: 44px; 59 padding: 20px 0 40px 50px; 60 } 61 .logo{ 62 width:200px; 63 } 64 .login-center { 65 width: 380px; 66 margin: 0 auto; 67 } 68 .center-wrap{ 69 position: absolute; 70 top: 50%; 71 right: 0; 72 left: 0; 73 width: 475px; 74 margin: auto auto; 75 -webkit-transform: translateY(-50%); 76 -moz-transform: translateY(-50%); 77 -ms-transform: translateY(-50%); 78 -o-transform: translateY(-50%); 79 transform: translateY(-50%); 80 } 81 .center-wrap .bd-logo img { 82 width: 248px; 83 height: 65px; 84 margin-left: 66px; 85 } 86 .center-wrap .z-bd { 87 position: relative; 88 overflow: hidden; 89 padding-bottom: 42px; 90 height: 350px; 91 background: url(../img/icloud-bar.png) no-repeat 0 bottom; 92 margin-top: 50px; 93 } 94 .z-bd .login-panel { 95 position: absolute; 96 left: 16px; 97 z-index: 2; 98 width: 302px; 99 height: 321px; 100 background: #fff; 101 background: rgba(255,255,255,.85); 102 border: none; 103 border-radius: 0; 104 color: #A1A1A1; 105 padding: 5px 70px 25px; 106 overflow: hidden; 107 box-shadow: 5px 2px 20px rgba(0,0,0,.3); 108 height:322px; 109 } 110 .z-bd .login-panel.cloud{ 111 left: auto; 112 right: 50px; 113 box-shadow: -5px 2px 20px rgba(0,0,0,.3); 114 } 115 .z-bd .login-cloud.ecshop{ 116 right: auto; 117 left: 50px; 118 background: -moz-linear-gradient(359deg, rgba(66,165,224,1) 0%, rgba(86,180,235,1) 100%); /* ff3.6+ */ 119 background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(66,165,224,1)), color-stop(100%, rgba(86,180,235,1))); /* safari4+,chrome */ 120 background: -webkit-linear-gradient(359deg, rgba(66,165,224,1) 0%, rgba(86,180,235,1) 100%); /* safari5.1+,chrome10+ */ 121 background: -o-linear-gradient(359deg, rgba(66,165,224,1) 0%, rgba(86,180,235,1) 100%); /* opera 11.10+ */ 122 background: -ms-linear-gradient(359deg, rgba(66,165,224,1) 0%, rgba(86,180,235,1) 100%); /* ie10+ */ 123 background: linear-gradient(91deg, rgba(66,165,224,1) 0%, rgba(86,180,235,1) 100%); /* w3c */ 124 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#42A5E0', endColorstr='#56B4EB',GradientType=1 ); /* ie6-9 */ 125 } 126 .z-bd .login-cloud.ecshop .btn-tab{ 127 background: url(../images/ecshop-n.png) no-repeat center center; 128 } 129 .z-bd .login-cloud.ecshop .btn-tab:hover{ 130 background: url(../images/ecshop-h.png) no-repeat center center; 131 } 132 .login-panel .panel-hd{ 133 padding-bottom: 10px; 134 line-height: 1; 135 font-size: 18px; 136 margin: 18px 0; 137 text-align: center; 138 font-weight: normal; 139 } 140 .login-panel .controls { 141 position: relative; 142 height: 51px; 143 border-left: 1px solid #ddd; 144 border-right: 1px solid #ddd; 145 border-bottom: 1px solid #ddd; 146 } 147 .login-panel .controls.first{ 148 border-radius: 5px 5px 0 0 ; 149 overflow: hidden; 150 border-top: 1px solid #ddd; 151 } 152 .login-panel .controls.first input{ margin:0; padding:1px 0;} 153 .login-panel .controls.two{ 154 border-radius:0 0 5px 5px; 155 overflow:hidden; 156 } 157 .login-panel .controls.two.active{ 158 border-radius:0; 159 } 160 .login-panel .controls.third{ 161 border-radius: 0 0 5px 5px ; 162 overflow: hidden; 163 display:none; 164 } 165 .login-panel .controls.third.active{ 166 display:block; 167 } 168 .login-panel .controls.last{ 169 border: none; 170 } 171 .login-panel input[type=text], .login-panel input[type=password] { 172 -webkit-appearance: none; 173 border: none; 174 background-color: #fff; 175 color: #8a8a8a; 176 width: 100%; 177 height: 48px; 178 line-height: 48px; 179 text-indent: 50px; 180 box-shadow: inset 30px 30px 0 30px #fff; 181 } 182 .login-panel .panel-bd { 183 height: 255px; 184 overflow: hidden; 185 } 186 .controls .iconphone { 187 display: block; 188 width: 20px; 189 height: 20px; 190 position: absolute; 191 left: 15px; 192 top: 15px; 193 z-index: 10; 194 } 195 .btn-a { 196 display: block; 197 color: #FFF; 198 width: 180px; 199 font-size: 16px; 200 line-height: 51px; 201 text-align: center; 202 background-color: #fc7878; 203 border: 0; 204 border-radius: 4px; 205 letter-spacing: 4px; 206 margin-top: 0px; 207 } 208 .login-panel .btn-a { 209 cursor: pointer; 210 width: 100%; 211 margin-top: 20px; 212 } 213 .login-panel .bside { 214 margin-top: 12px; 215 overflow: hidden; 216 height: auto; 217 } 218 .login-panel .bside input[type="checkbox"] { 219 float: left; 220 width: 15px; 221 height: 15px; 222 margin: 2px 8px 0 0; 223 } 224 .login-panel .bside label { 225 color: #666; 226 float: left; 227 } 228 .login-panel .bside a { 229 float: right; 230 display: inline-block; 231 text-align: right; 232 } 233 .login-panel .bside .link-forget{ 234 float:left; 235 margin-left: 25px; 236 } 237 .login-cloud{ 238 position: absolute; 239 right: 50px; 240 z-index: 1; 241 padding: 35px 25px 20px; 242 margin: 0 auto; 243 width: 200px; 244 height: 297px; 245 color: #fff; 246 text-align: center; 247 background: -moz-linear-gradient(359deg, rgba(238,128,53,1) 0%, rgba(251,164,105,1) 100%); /* ff3.6+ */ 248 background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(238,128,53,1)), color-stop(100%, rgba(251,164,105,1))); /* safari4+,chrome */ 249 background: -webkit-linear-gradient(359deg, rgba(238,128,53,1) 0%, rgba(251,164,105,1) 100%); /* safari5.1+,chrome10+ */ 250 background: -o-linear-gradient(359deg, rgba(238,128,53,1) 0%, rgba(251,164,105,1) 100%); /* opera 11.10+ */ 251 background: -ms-linear-gradient(359deg, rgba(238,128,53,1) 0%, rgba(251,164,105,1) 100%); /* ie10+ */ 252 background: linear-gradient(91deg, rgba(238,128,53,1) 0%, rgba(251,164,105,1) 100%); /* w3c */ 253 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ee8035', endColorstr='#fba469',GradientType=1 ); /* ie6-9 */ 254 } 255 .login-cloud .hd{ 256 line-height: 50px; 257 font-size: 18px; 258 } 259 .login-cloud p{font-size: 16px;} 260 .login-cloud .hd span{ 261 color: #c2bfbd; 262 } 263 .login-cloud .btn-tab{ 264 display: block; 265 width: 110px; 266 height: 110px; 267 background: url(../images/cloud-n.png) no-repeat center center; 268 margin: 50px auto 20px; 269 } 270 .login-cloud .btn-tab:hover{ 271 background: url(../images/cloud-h.png) no-repeat center center; 272 } 273 .login-cloud img{ 274 width: 100%; 275 cursor: pointer; 276 } 277 .cloud-passw{ 278 margin-top: 20px; 279 } 280 .personal-set{ 281 position: relative; 282 } 283 .personal-set .panel-hint{ 284 display: none; 285 position: absolute; 286 margin: 0; 287 left: -7px; 288 top: 10px; 289 height: auto; 290 width: 82px; 291 padding-top: 10px; 292 background-color: transparent; 293 border-radius: 5px; 294 box-shadow: none; 295 } 296 .personal-set .panel-hint ul{ 297 position: relative; 298 background: #fff; 299 border-radius: 5px; 300 box-shadow: 0 0 1px rgba(0,0,0,.3); 301 } 302 .personal-set .panel-hint ul:before{ 303 content: ''; 304 position: absolute; 305 top: -9px; 306 right: 35px; 307 border: 5px solid transparent; 308 border-bottom: 5px solid #fff; 309 } 310 #submenu-div .personal-set li{ 311 float: initial; 312 padding: 0; 313 margin: 0; 314 border-left: none; 315 color: #ddeef2; 316 } 317 .personal-set li a{ 318 display: block; 319 padding-left: 5px; 320 line-height: 20px; 321 color: #696969 !important; 322 background-color: transparent; 323 } 324 .personal-set li a:hover{ 325 color: #000; 326 background-color: #ddeef2; 327 box-shadow: 0 1px 1px 1px #ddd; 328 } 329 .personal-set .btn-first a{ 330 border-radius: 5px 5px 0 0; 331 } 332 .personal-set .btn-first a:hover{ 333 box-shadow: 0 1px 1px 1px #ddd; 334 } 335 .personal-set .btn-exit a{ 336 border-radius: 0 0 5px 5px; 337 border-top: 1px solid #ddd; 338 }
4.新建一个poi.css文件
1 .poi_note { 2 background-color: white; 3 } 4 5 .poi_title { 6 font-size: 40px; 7 font-weight: bold; 8 text-align: center; 9 padding: 40px; 10 } 11 12 .poi_author { 13 margin: 30px 0 40px; 14 padding-left: 50px; 15 } 16 17 .poi_avatar img { 18 width: 96px; 19 border: 1px solid #ddd; 20 border-radius: 50%; 21 } 22 23 .poi_info { 24 vertical-align: middle; 25 display: inline-block; 26 margin-left: 8px; 27 } 28 29 .poi_name { 30 margin-right: 3px; 31 font-size: 25px; 32 vertical-align: middle; 33 font-weight: bold; 34 padding-right: 20px; 35 } 36 37 .poi_meta { 38 padding-top: 12px; 39 font-size: 20px; 40 color: #969696; 41 } 42 43 .poi_meta span { 44 margin-right: 5px; 45 } 46 47 .poi_show-content { 48 color: #2f2f2f; 49 font-size: 16px; 50 font-weight: 400; 51 line-height: 1.7; 52 padding-left: 50px; 53 padding-right: 50px; 54 } 55 56 .poi_show-content p { 57 text-indent: 20px; 58 margin: 0 0 25px; 59 } 60 61 .poi_show-foot { 62 margin: 40px 0 30px; 63 padding-left: 50px; 64 padding-right: 50px; 65 } 66 67 .poi_copyright { 68 float: right; 69 margin-top: 5px; 70 font-size: 12px; 71 line-height: 1.7; 72 color: #9b9b9b; 73 } 74 75 .poi_modal-wrap { 76 float: right; 77 margin-top: 5px; 78 margin-right: 20px; 79 font-size: 12px; 80 line-height: 1.7; 81 } 82 83 .poi_follow-detail { 84 padding: 20px; 85 background-color: hsla(0, 0%, 71%, .1); 86 border: 1px solid #e1e1e1; 87 border-radius: 4px; 88 font-size: 12px; 89 margin: 20px; 90 } 91 92 .poi_signature { 93 margin-top: 20px; 94 padding-top: 20px; 95 border-top: 1px solid #e1e1e1; 96 color: #969696; 97 overflow: hidden; 98 text-overflow: ellipsis; 99 white-space: nowrap; 100 } 101 102 .poi_info.poi_avatar { 103 float: left; 104 margin-right: 10px; 105 width: 48px; 106 height: 48px; 107 } 108 109 .poi_info p { 110 margin-bottom: 0; 111 color: #969696; 112 padding-left: 130px; 113 margin-top: -20px; 114 } 115 116 .right { 117 margin-top: 30px; 118 float: right; 119 } 120 121 .poi_post { 122 padding-bottom: 20px; 123 } 124 125 .new-comment { 126 position: relative; 127 margin-left: 48px; 128 } 129 130 .poi_sign-container { 131 text-align: center; 132 width: 90%; 133 height: 80px; 134 font-size: 13px; 135 border: 1px solid #dcdcdc; 136 border-radius: 4px; 137 background-color: hsla(0, 0%, 71%, .1); 138 resize: none; 139 display: inline-block; 140 vertical-align: top; 141 outline-style: none; 142 margin-left: 30px; 143 padding-top: 30px; 144 } 145 146 .poi_comment-list { 147 background-color: white; 148 } 149 150 .sign-container { 151 margin-right: 20px; 152 margin-left: -20px; 153 } 154 155 .poi_top-title { 156 padding-bottom: 20px; 157 font-size: 17px; 158 font-weight: 700; 159 border-bottom: 1px solid #f0f0f0; 160 } 161 162 .poi_author-only { 163 margin-left: 10px; 164 padding: 4px 8px; 165 font-size: 12px; 166 color: #969696; 167 border: 1px solid #e1e1e1; 168 border-radius: 12px; 169 } 170 171 .pull-right { 172 float: right !important; 173 } 174 175 .pull-right a { 176 margin-left: 10px; 177 font-size: 12px; 178 font-weight: 400; 179 color: #969696; 180 display: inline-block; 181 } 182 183 .poi_comment_item { 184 margin: 10px 10px 10px 10px; 185 border: 1px solid rgba(0, 0, 0, 0.17); 186 background-color: rgba(0, 0, 0, 0.02); 187 border-radius: 5%; 188 } 189 190 .poi_comment-wrap { 191 margin: 50px 50px 15px 50px; 192 font-size: 20px; 193 text-indent: 20px; 194 } 195 196 .poi_comment-wrap p { 197 line-height: 1.7; 198 } 199 200 .poi_tool-group { 201 margin-top: 30px; 202 }
5.新建一个posted.css文件
1 .posted_box{ 2 border:1px solid #eeeeee; 3 padding: 50px 50px 50px 0px; 4 background-color: #d7d7d7; 5 }
6.新建一个second.css文件
1 body{ 2 background-color: rgba(6, 6, 6, 0.1); 3 } 4 .regis_box { 5 border: 1px solid #A1A1A1; 6 padding: 20px 20px 40px 20px; 7 height: 300px; 8 width: 500px; 9 margin-top: 15%; 10 margin-left: 27%; 11 12 } 13 .regis_box_off{ 14 background-color: #DDDDDD; 15 } 16 .regis_box_on{ 17 background-color: #FFFFFF; 18 } 19 20 .font_title { 21 font-size: 20px; 22 font-weight: bold; 23 } 24 25 .btn_submit_regis { 26 text-align: center; 27 } 28 29 .navbar-header { 30 float: left; 31 } 32 33 nav{ 34 position:fixed; 35 top:0px; 36 height: 60px; 37 background-color:#FCFCFC; 38 border-bottom:1px solid #DDDDDD; 39 width:100%; 40 z-index: 999; 41 } 42 43 .on{ 44 background-color: #EEEEEE; 45 } 46 47 .off{ 48 background-color: #000000; 49 } 50 51 footer{ 52 position:relative; 53 bottom:0; 54 width:100%; 55 float: left; 56 } 57 58 footer .footer_box{ 59 background-color: #002D54; 60 padding: 10px; 61 color : #FFFFFF; 62 text-align: center; 63 } 64 65 .box{ 66 margin-top: 60px; 67 min-height: 800px; 68 } 69 .index_box{ 70 margin-top: 58px ; 71 } 72 73 .dd-item{ 74 color: black; 75 font-size: 10px; 76 text-align: center; 77 }
project.py文件插入以下代码:
1 登录 2 @app.route('/login/', methods=['GET', 'POST']) 3 def login(): 4 if request.method == 'POST': 5 user_name = request.form.get('user_name') 6 user_password = request.form.get('user_password') 7 user = User.query.filter(User.name == user_name, 8 User.password == md5(user_password.encode("utf-8")).hexdigest()).first() 9 if user: 10 session['user_id'] = user.id 11 session['title'] = user.title 12 session.permanent = True 13 poi = request.args.get('poi') 14 if poi: 15 return poi 16 return 'index' 17 else: 18 return '用户或密码错误' 19 else: 20 return render_template('login.html') 21 22 # 上下文处理器 23 @app.context_processor 24 def myContext(): 25 id = session.get('user_id') 26 title = session.get('title') 27 if id: 28 user = User.query.filter(User.id == id).first() 29 else: 30 user = {} 31 if title: 32 return {'title': title, 'user_id': id, 'user': user} 33 else: 34 return {} 35 36 # 注册 37 @app.route('/regist/', methods=['GET', 'POST']) 38 def regist(): 39 if request.method == 'GET': 40 user_name = request.args.get('user_name') 41 if user_name: 42 user = User.query.filter(User.name == user_name).first() 43 if user: 44 return '用户已存在' 45 else: 46 return 'ok' 47 else: 48 return render_template('regist.html') 49 else: 50 user_name = request.form.get('user_name') 51 user_title = request.form.get('user_title') 52 user_password = request.form.get('user_password') 53 user = User.query.filter(User.name == user_name).first() 54 if user: 55 return 'error:user exitst' 56 else: 57 user = User(id="1", name=user_name, title=user_title, password=user_password) 58 db.session.add(user) # 加入数据库 59 db.session.commit() 60 return redirect(url_for('login')) 61 62 # 定义一个装饰器出验证用户有是否是登陆 63 # 定义一个参数函数 64 def loginFirst(func): 65 # 定义一个函数将其返回 66 @wraps(func) 67 def wrapper(*args, **kwargs): 68 if session.get('title'): 69 return func(*args, **kwargs) 70 else: 71 return redirect(url_for('login')) 72 73 # 返回一个函数 74 return wrapper 75 76 # 发布问答 77 @app.route('/question', methods=['GET', 'POST']) 78 @loginFirst 79 def question(): 80 if request.method == 'GET': 81 classfly = Classification.query.all() 82 context = { 83 'classfly' : classfly 84 } 85 return render_template('question.html',**context) 86 else: 87 book_title = request.form.get('title') 88 book_content = request.form.get('content') 89 abstracts = request.form.get('abstracts') 90 classification = request.form.get('classification') 91 user_id = request.form.get('user_id') 92 size = request.form.get('size') 93 book = Book(id='1', title=book_title, abstracts=abstracts, content=book_content, author_id=user_id,classification=classification,size=size) 94 db.session.add(book) # 加入数据库 95 db.session.commit() 96 return 'true' 97 98 # 详情页面 99 @app.route('/poi/<book_id>') 100 def poi(book_id): 101 book = Book.query.filter(Book.id == book_id).first() 102 answer = len(Commentaries.query.filter(Commentaries.book_id==book_id).all()) 103 book.chilk = book.chilk+1 104 db.session.commit() 105 id = session.get('user_id') 106 if id: 107 user = User.query.filter(User.id == id).first() 108 else: 109 user = {} 110 return render_template('poi.html', book=book, user=user,answer=answer) 111 112 # 点赞 113 @app.route('/disc/') 114 def disc(): 115 book_id = request.args.get('book_id') 116 book = Book.query.filter(Book.id == book_id).first() 117 book.disc = book.disc+1 118 db.session.commit() 119 return str(book.disc) 120 121 # 发布评论 122 @app.route('/answer/', methods=['GET', 'POST']) 123 def answer(): 124 if request.method == 'POST': 125 book_id = request.form.get('book_id') 126 question_id = request.form.get('question_id') 127 answer_id = request.form.get('answer_id') 128 content = request.form.get('content') 129 commentaries = Commentaries(id='1', book_id=book_id, question_id=question_id, answer_id=answer_id, 130 content=content) 131 db.session.add(commentaries) 132 db.session.commit() 133 commentaries = Commentaries.query.filter(Commentaries.book_id == book_id).order_by('-date').all() 134 context = { 135 'commentaries': commentaries, 136 } 137 return render_template('answer.html', **context) 138 else: 139 book_id = request.args.get('book_id') 140 commentaries = Commentaries.query.filter(Commentaries.book_id == book_id).order_by('-date').all() 141 context = { 142 'commentaries': commentaries, 143 } 144 return render_template('answer.html', **context) 145 146 # 某用户发布过的所有评论 147 @app.route('/commentaries/<user_id>',methods=['GET','POST']) 148 def commentaries(user_id): 149 user = User.query.filter(User.id == user_id).first() 150 content = { 151 'userCommentaries':user.commentaries, 152 'books':user.book, 153 'num': len(user.commentaries), 154 'user2':user 155 } 156 return render_template('commentaries.html', **content) 157 158 # 设置中心 159 @app.route('/config/<user_id>',methods=['GET','POST']) 160 @loginFirst 161 def config(user_id): 162 user = User.query.filter(User.id == user_id).first() 163 if request.method == 'GET': 164 return render_template('config.html') 165 else: 166 user.title = request.form.get('title') 167 user.truename = request.form.get('truename') 168 user.sex = request.form.get('sex') 169 user.qq = request.form.get('qq') 170 user.phone = request.form.get('phone') 171 user.email = request.form.get('email') 172 user.address = request.form.get('address') 173 db.session.commit() 174 return render_template('config.html') 175 176 # 上传头像 177 @app.route('/uploadLogo/<user_id>',methods=['GET','POST']) 178 def uploadLogo(user_id): 179 user = User.query.filter(User.id == user_id).first() 180 f = request.files['logo'] 181 basepath = os.path.dirname(__file__) # 当前文件所在路径 182 upload_path = os.path.join(basepath, 'static/uploads', f.filename) # 注意:没有的文件夹一定要先创建,不然会提示没有该路径 183 f.save(upload_path) 184 user.logo = 'uploads/'+f.filename 185 db.session.commit() 186 return '{"url":"'+url_for('static',filename='uploads/'+f.filename)+'"}'; 187 188 # 分类列表 189 @app.route('/classflyList/') 190 def classflyList(): 191 classfly = Classification.query.all() 192 context = { 193 'classfly':classfly 194 } 195 return render_template('classflyList.html',**context) 196 197 # 某个分类下的文章 198 @app.route('/classfly/<classification_id>') 199 def classfly(classification_id): 200 classflyList = Classification.query.all() 201 classfly = Classification.query.filter(Classification.id == classification_id).first() 202 context = { 203 'classfly': classfly, 204 'books':classfly.book, 205 'classflyList': classflyList 206 } 207 return render_template('classfly.html',**context) 208 209 # 改密码 210 @app.route('/resetPassword/<user_id>', methods=['GET', 'POST']) 211 @loginFirst 212 def resetPassword(user_id): 213 user = User.query.filter(User.id == user_id).first() 214 if request.method == 'GET': 215 return render_template('resetPassword.html') 216 else: 217 password = request.form.get('password') 218 oldPassword = request.form.get('oldPassword') 219 if(md5(oldPassword.encode("utf-8")).hexdigest()==user.password): 220 user.password = md5(password.encode("utf-8")).hexdigest() 221 db.session.commit() 222 else: 223 return '原密码有误'; 224 return render_template('resetPassword.html') 225 226 # 模糊查找 227 @app.route('/search', methods=['GET', 'POST']) 228 def search(): 229 qu = request.args.get('q') 230 query = Book.query.filter( 231 or_( 232 Book.title.contains(qu), 233 Book.content.contains(qu), 234 ) 235 ).order_by('-createdate').all() 236 classfly = Classification.query.all() 237 context = { 238 'books': query, 239 'classfly':classfly 240 } 241 return render_template('home.html', **context) 242 243 # 首页 244 @app.route('/', methods=['GET', 'POST']) 245 def index(): 246 # context = { 247 # 'userName' : "AllianceHacker", 248 # 'toTime' : '11小时前', 249 # 'title' : 'PHP是世界是最好的语言', 250 # 'context' : 'PHP是世界是最好的语言,这是一个不需要有疑问的问题,谁不服可以来战啊!!!' 251 # } 252 books = Book.query.order_by('-createdate').all() 253 classfly = Classification.query.all() 254 context = { 255 'books': books, 256 'classfly':classfly 257 } 258 return render_template('home.html', **context)
运行项目,打开首页,对成功了吧(我们来测试一下我们的功能)
一、注册
二、登录
三、发布
四、查看