个人总结
本学期第一次接触web前端开发技术,以前完全没有接触过Python+Flask+MysqL这些工具和技术,对这些技术比较陌生,上手也表较慢。所以在空闲时间会在网上找一些关于这些技术的资料来了解并熟悉它要如何搭建。了解到要运用到HTML,CSS、Javascript的一些基础。听说前端开发是个非常新的职业,对一些规范和最佳实践的研究都处于探索阶段。总有新的灵感和技术不时闪现出来,例如CSS sprite、负边距布局、栅格布局等;各种JavaScript框架层出不穷,为整个前端开发领域注入了巨大的活力;浏览器大战也越来越白热化,跨浏览器兼容方案依然是五花八门。
为了满足“高可维护性”的需要,需要更深入、更系统地去掌握前端知识,这样才可能创建一个好的前端架构,保证代码的质量。在进入学习和实操页面设计前,老师教了我们一些输入输出语句,Turtle库,用它来绘制图像,想象一个小乌龟,在一个横轴为x、纵轴为y的坐标系原点,(0,0)位置开始,它根据一组函数指令的控制,在这个平面坐标系中移动,从而在它爬行的路径上绘制了图形。还有了解一些函数,语句,管理信息系统上一些章节的概念简述等等。这些都是为接下来真正实现web前端开发做基础。
真正用web技术来制作网页时,我发现并不是那么简单就可以实现的。因为有时候会因为一个字母,一个符号,导致一个小小的功能就实现不了。我从老师开始教web要如何搭建自己要设计的主题网站。跟着老师的方法和步骤一步一步的学习,在这十几周的学习期间中,用的最多的技术就是JavaScript、HTML、CSS,因为它可以为网页添加一些有特色的效果,丰富自己的网页内容。期间我遇到最大的困难就是练习的过程中,不就是代码写漏了,不就是html网页代码与后端代码不匹配,导致浪费了很多时间都无法发现问题出错在哪。在排查漏洞这个过程,才是最痛苦的。每次一看到错误,改正之后又出现了不同的错误。这也是因为本人在编辑时过于粗心,没有彻底懂得代码的意思之后再下手,以至于每一次交作业的时间都会比别人慢了一点。这样的状态持续了几周之后,发现自己到后来已经可以慢慢的跟上老师的思维和节奏去编辑自己的东西了,也不会像最开始那样不知道要从哪里下手,错误情况也不少了一点。在做CSS或者是其他的语言的时候,慢慢的你会发现,完成一份工作,总是有很多种方式,很多时候你会困惑,我究竟该用哪些方式好?这个在项目中,就叫做最佳实践,换句话说。最佳实践就是无数人走了无数的弯路,告诉你那么走是走不通的,按照正确的方法走是没问题的。所以我在遇到问题时,如果自己摸索不出情况下,更多的是百度或请求同学,每个人都有自己的学习方式,都有自己无法理解的问题和困扰,这些只能靠真正的写代码去实践出来的。
我发现学习的氛围很重要,讨论交流,同学都在努力学习的氛围会让你不自然的向前走。虽然我的设计中存在很多不足之处,但是我会尽力把它最好。大家都知道后端代码其实才是神一样的存在,无论前端是有Apple还是IOS还是桌面客户端,永远少不了后端,后端要懂业务逻辑,要懂扩展,要懂备份和安全。但是我们更多时间是花在前端的学习上,这门课主要是要我们更多掌握前端开发的一些知识。我的原则是永远记住着代码是写出来的,不是看出来的;要有自己独立学习独立解决问题的能力;记着不要说自己不会英语;记着要学的知识有很多,找到一条正确的途径才可以。
我的学习经验:尽量看视频加上实际操作来学习,跟着老师的节奏来。因为从课堂上学习东西比较系统,学到的东西是系统的而不是一片一片或者一点一点的。最重要的是要去不断是验证跟实战的结果进行对比,你会发现实际可能还真不一定是那样的。等系统学习完之后,再要提高可能就要找论坛,博客等针对某个点进行突破,后面的成长还有很长。个人能力不到那个地方不在妄加说辞。1.千万注意写代码、和命名规范;2.html的文档结构,好的文档结构会让你写css,js变的简单合理;3.尽量尽自己的水平优化代码html,css,js,因为每一次优化都是对你学习的提高。4.多去一些有用的网站上其他人是如何布局更多的页面出来,如知乎、简书、猫眼等等,它可以很清晰地了解到代码是如何实现的。模仿其他人的代码,创造属于自己的页面。记得,每个web前台开发工程师都应该具有很强的想象力,发挥想象力,并去验证自己的想法才会提高。
目前个人的水平还是非常有限的,就只能分享这么多了。本人自己设计的网页存在很多不足需要改进。这十几周的学习使我懂得了这个技术的强大之处,也让我收获了很多知识,培养了自己的思考能力与耐心地观察能力。在以后实习中如果从事在与本课程相关的工作的话,我会将更深层次学习web前端开发技术。做这种东西,应该要一颗为不断实践而去坚持到底的心。要有明确的学习规划;要不断的用代码去验证自己学习的成果;要学会自己去主动解决问题;要学会自己去和其他人交流请教;每天都去总结反馈;公开代码,接受交流;不要太贪心,什么都想学。虽然自己还没办法做到以上的要点,但希望其他的小伙伴能尽量掌握以上几个要点,这样去实现属于自己的网页才较快入手。
总结Python+Flask+MysqL的web建设技术过程
一、前期准备
Web的开发环境一般是Python+Flask+MysqL;所以在搭建属于自己的平台之前需要在你的电脑上安装python;
- 安装python
Python文档下载地址:www.python.org/doc/;选择适合自己电脑版本的进行下载。也可以进入python官网:http://www.python.org/下载完后可以通过终端窗口输入 "python" 命令来查看本地是否已经安装Python以及Python的安装版本。也可以在不同平台上安装python,如Unix&Linux或者window上安装,具体请前往: http://www.python.org/download/;并把安装好的python放在指定路径下。
2、Python环境变量配置
程序和可执行文件可以在许多目录,而这些路径很可能不在操作系统提供可执行文件的搜索路径中。path(路径)存储在环境变量中,这是由操作系统维护的一个命名的字符串。这些变量包含可用的命令行解释器和其他程序的信息。把安装好的python路径置于环境变量中。进行这一步时需要特别注意的是路径copy的路径是否是正确,以免在终端窗口输入时,总是显示:不是内部或外部文件,这个是许多人会犯的错误。C:\Python 是Python的安装目录。可以通过以下方式设置:
- 右键点击"计算机",然后点击"属性"
- 然后点击"高级系统设置"
- 选择"系统变量"窗口下面的"Path",双击即可!
- 然后在"Path"行,添加python安装路径即可(我的C:\Users\Acer\AppData\Local\Programs\Python\Python36\Scripts\;),所以在后面,添加该路径即可。 ps:记住,路径直接用分号";"隔开!
- 最后设置成功以后,在cmd命令行,输入命令"python",就可以有相关显示。
3、运行Python
我是通过命令行窗口进入python并开在交互式解释器中开始编写Python代码。
4、集成开发环境:PyCharm
老师为了方便学生学习,老师把整个PyCharm 文件提供给我们,我们只需要进去bin目录中选择pychranmy64.exe即可,但用了时间之后就过过期,所以个人建议到网站重新下载。PyCharm 下载地址 : https://www.jetbrains.com/pycharm/download/;下载完即可打开:
二、开始使用web元素制作html
- 创建html文件
在templates目录下创建html文件,可以开始进行自己的网站设计,从html文件中的body部分进行扩充,同时注意学会在出错时按F12去检查自己所写代码结果并学会观察和改正代码写法。
2、熟悉布局+样式
布局是最基础的操作,先抛开各种奇怪的控制的属性不谈,单说各种对齐和局中。这里其实是需要了解一些理论知识的(大概也是CSS里为数不多的理论知识之一),主要就是盒子模型,定位(标准流)(浮动)(相对,绝对)。用这些东西做出常见的居中,两列,三列,Header,Foot,侧边栏等。 然后就是学习各种控件(简单的和复杂的)的样式,这里包括选择器,优先级等等。
老师让我们教我们利用简单元素完成了几个作业;有导航、图片导航、css基础、JavaScript 基础,还有登录和注册的前端页面;每一次作业都必须在指定时间内完成。
三、Flask项目与连接数据库
- 新建flask项目
在pychranmy右上角文件那里点击new project,选择flask,并根据自己喜好为项目定义一个名字。
2、运行/调试配置
注意是在你创建的flask中编辑结构,并选择在python路径下
3、导入和实行命令
- 先导入flask,实例对象,输入代码如下:
- 再使用装饰器,设置路径与函数之间的关系;
- 使用Flask中render_template,用不同的路径,返回到不同页;
- 用视图函数反转得到URL,完成导航里的链接;代码如下:
这时我们运行run.py,然后,访问http://127.0.0.1:5000/就返回到base页面。
4、导入相关的库与包
from flask import Flask, render_template, request, redirect, url_for, session from flask_sqlalchemy import SQLAlchemy import config from functools import wraps from datetime import datetime from werkzeug.security import generate_password_hash,check_password_hash from sqlalchemy import or_, and_
5、连接数据库设置
四、学习期间
每次学习web框架和完成作业时,我都会上菜鸟编程这个网站了解一下关于js教程、css、html元素中的一些布局,经常上网借鉴Bootstrap,学会了解使用开源框架的感受,学习别人封装代码的思路,可以帮助你从另一个角度去思考,让你的代码更简洁,这是最重要的。
刚开始自己在设计网站时走了很多弯路,布局了一个页面,写了一些css元素进去后,打开网站后发现格局还是很丑,不是自己想要的效果,也不会如何去变通老师教给的知识。更多的是请教其他同学,也听了老师的一些意见,模范其他网站的布局与写法,创造属于自己的网站。老师每次讲课都会以简书或者知乎网站为例子,我也开始学会去抓去我要的一些代码,丰富自己的页面。个人小建议:
- 找到一个模板
- 边修改模板,边查阅资料,以此来完成一个应用
- 阅读官方文档或者代码来补漏
- 编写博客、文章、书籍来加强印象
练习,那可是相当烧时间的大事;时间,又是一种相宝贵的资源。遇到最大的问题就是代码泄漏或者代码理解不够导致前后代码不一致导致出现错误情况,而检查到出错和改正错误是一项令很头痛的事情。对于我这个粗心大意又急性子的人来说,每一次作业几乎都会出现这些细节上的错误。几周后,我学会跟着老师的教学思路去理解代码,虽然还是很多不懂,但最起码不会经常出错,也不会浪费时间不断检查代码。思路也慢慢清晰了,这对于以后进一步学习吸收了经验。
五、我的项目
- 设计概况
我为自己设计的网页主题是“娱乐圈明星聊”,因为现在好多人多多少少都会关注娱乐圈中的新闻,所以我决定简单设计一个关于娱乐圈的网页,实现一些简单的功能。有详情、评论页和发布功能,可以让更多的人到网站上去展开自己的想法和话题。在实现老师交代的一些必须完成的功能后,我自己在首页多做了一个点赞功能,在详情内容上为读者对自己喜欢的文章提供点赞的机会;还增加一个修改密码和文章分类的功能,为使用者提供多一些功能。
2、风格定位
- 色彩是以浅灰色为主,简洁清新,以便浏览者一眼就寻找到自己想要欣赏的东西。网站的色彩具有一致性,会使网站看起来美观,使浏览者不容易对内容混淆,增加浏览的简介和方便,不感觉到观看娱乐新闻的那种复杂性。
- 排版分为三个部分:头部导航条、底部图片导航、中间主显示区域布局。头部和底部分别设置导航栏,底部导航还融入图片等一些元素。中间布局融入了自己喜欢的明星的一些东西进去。
- 特效:网站的特效就是让网页看起来生动活泼的各种应用,如Flask、JavaScript等。设计中用一颗“灯泡”对白天和黑夜模式进行设置,还有对字体颜色和效果简单设置等。
3、网站栏目划分
父模版(base.html)
首页(shouye.html)
个人中心(usercenter.html)
详情页(xiangqing.html)
登录页(login.html)
注册页(regist.html)
问题(question.html)
修改密码(edit_password.html)
六、Web前端与后端设计主要代码
- 父模版
前端:
<body id="myBody" bgcolor="#e9967a" style="background-image: url('http://www.rmzt.com/uploads/allimg/160218/1-16021Q52256.jpg');"> </a> <a href="{{ url_for('logout') }}"> <button type="button" class="btn btn-default"><span class="glyphicon glyphicon-user"></span> 注销 </button> </a> {% else %} <a href="{{ url_for('login') }}"> <button ty<nav class="navbar navbar-default" role="navigation" style="color: darksalmon"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="https://www.4493.com/star/section?fenlei=1&quyu=1&sex=1" style="color: palevioletred">演员列表</a> </div> <div>
<nav class="navbar navbar-default navbar-fixed-bottom" role="navigation"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="#" style="color: palevioletred">重磅娱乐新闻</a> </div> <div> <ul class="nav navbar-nav"> <li><a href="http://music.baidu.com/?fr=baikePC">今日头条:<img src="http://pic.meituba.com/uploads2/allimg/171213/0Z5222614-3.jpg" style="width: 59px"></a> </li> <li><a href="http://slide.ent.sina.com.cn/film/">今日电影:<img src="http://s.img.mix.sina.com.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/ent/transform/w600h400/20171218/YmmS-fypsqka7042464.jpg" style="width: 59px"></a></li> <li><a href="http://slide.ent.sina.com.cn/star/slide_4_704_258710.html/d/1#p=1">今日明星:<img src="http://n.sinaimg.cn/ent/4_img/upload/d411fbc6/w900h670/20171218/LLQv-fypsqka7093197.jpg" style="width: 59px"></a></li> <li><a href="#">今日微博:<img src="https://ss0.baidu.com/73t1bjeh1BF3odCf/it/u=960352973,2105741994&fm=85&s=A722C9A70042B1FD0001892D03001040" style="width:59px"></a></li> </ul> </div> </div> </nav>
后台:
@app.route('/') def base(): return render_template('base.html')
2、首页
前端:
{% for foo in questions %} <a href="{{ url_for('usercenter',user_id=foo.author_id,tag=1) }}">呆梨:{{ foo.username }}</a> <a href="{{ url_for('xiangqing',question_id=foo.id ) }}">问题:{{ foo.title }}</a><br> <p style="color: indianred">详情:{{ foo.detail }}</p> <a class="collection-tag" target="_blank" href="/c/Df7njb" style="border: 1px solid palevioletred">谈娱乐</a> <span class="badge">首播时间:{{ foo.creat_time }}</span><br> </li> {% endfor %}
后端:
@app.route('/shouye/') def shouye(): context = { 'questions': Question.query.order_by('-creat_time').all() } return render_template('shouye.html', **context)
3、登录
前端:
<form action="{{ url_for('login') }}" method="post"> <div class="input_box"> username:<input id="name" type="username" placeholder="请输入用户名" name="username"> </div> <div class="input_box"> password:<input id="pass" type="password" placeholder="请输入密码" name="password"> </div> <button class="btn btn-info" οnclick="return fnLogin()" style="width: 380%">login</button><br> <a class="link-forget cl-link-blue" href="regist.html">忘记密码</a> </form>
后端:
@app.route('/login/', methods=['GET', 'POST']) # methods定义它有两种请求方式 def login(): if request.method == 'GET': return render_template('login.html') else: usern = request.form.get('username') # post请求模式,安排对象接收数据 passw = request.form.get('password') user = User.query.filter(User.username == usern).first() # 作查询,并判断 if user: # 判断用户名 if user.check_password(passw): # 判断密码 session['user'] = usern # 利用session添加传回来的值username session['userid']=user.id session.permannet = True return redirect(url_for('shouye')) else: return '密码错误' else: return '用户名不存在,请先注册'
4、注册
前端:
<form action="{{ url_for('regist') }}" method="post"> <div class="input_box"> username:<input id="zcuname" type="username" placeholder="请输入用户名" name="username"> </div> <div class="input_box"> password:<input id="zcupassword1" type="password" placeholder="请输入密码" name="password"> </div> <div class="input_box"> password:<input id="zcupassword2" type="password" placeholder="请再次输入密码"> </div> <div id="zcerror_box"><br></div> <div class="input_box"> <button type=submit class="btn btn-info" οnclick="fnEnroll()" style="width: 380%">立即注册 </button> <a href="login.html">已注册</a></div> </form>
后端:
@app.route('/regist/', methods=['GET', 'POST']) # methods定义它有两种请求方式,因为它在表单的请求是post def regist(): if request.method == 'GET': return render_template('regist.html') else: username = request.form.get('username') # post请求模式,安排对象接收数据 password = request.form.get('password') user = User.query.filter(User.username == username).first() # 作查询,并判断 if user: return 'username existed' else: user = User(username=username, password=password) # 将对象接收的数据赋到User类中,即存到数据库 db.session.add(user) # 执行操作 db.session.commit() return redirect(url_for('login')) # redirect重定向
5、个人中心
前端:
<li class="nav-item"> <a class="nav-link" href="{{ url_for('usercenter',user_id=user.id,tag='1')}}">全部问题</a> </li> <li class="nav-item"> <a class="nav-link" href="{{ url_for('usercenter',user_id=user.id,tag='2')}}">全部评论</a> </li> <li class="nav-item"> <a class="nav-link disabled" href="{{ url_for('usercenter',user_id=user.id,tag='3')}}">个人信息</a> </li>
后端:
@app.route('/usercenter/<user_id>/<tag>') # 为了把页面分开,我们在html页面传了一个tag参数 @loginFirst def usercenter(user_id,tag): user=User.query.filter(User.id==user_id).first() context={ 'number': user.id, 'user':user, 'question': user.question, 'comments': user.comments } # 根据tag的不同去到不同页面,一个请求跳转3个不同页面 if tag=='1': return render_template('usercenter1.html',**context) elif tag=='2': return render_template('usercenter2.html',**context) else: return render_template('usercenter3.html',**context)
6、详情页
前端:
<form action="{{url_for('comment')}}" method="post" style="margin: 20px"> <div class="form-group"> <textarea name="new_comment" class="form-control" rows="5" id="new-comment" placeholder="Write your comment~" style="width: 850px"></textarea><br> <input name="question_id" type="hidden" value="{{ ques.id }}"> </div> <button type="submit" class="btn btn-default" style="background-color: #4CAF50">发送 </button> </form> <h4>comment:({{ ques.comments|length }})</h4> <ul class="list-unstyled" style="width: 900px"> {% for foo in comments %} <li class="list-group-item"> <a href="{{ url_for('usercenter',user_id=foo.author.id,tag=1) }}">{{ foo.author.username }}</a> <span class="badge pull-right">{{ foo.creat_time }}</span> <p>{{ foo.detail }}</p> <br> </li> {% endfor %}
后端:
@app.route('/xiangqing/<question_id>') def xiangqing(question_id): quest = Question.query.filter(Question.id == question_id).first()# 根据主页带回来的id查询出整条元组记录,传到question comments = Comment.query.filter(Comment.question_id==question_id).all() # 根据question的id在Comment查询出所有评论 return render_template('xiangqing.html', ques=quest,comments=comments)
7、问题页
前端:
<form action="{{ url_for('question') }}" method="post"> <div class="box"> <label for="question">问题</label> <textarea class="form-control" rows="3" id="question" placeholder="问题" name="title" id="title" style="width: 500px" ></textarea> <label for="questionDetail">详情</label> <textarea class="form-control" rows="3" id="questionDetail" placeholder="详细评论" name="detail" id="detail" style="width: 500px"></textarea> </div> <br> <div class="input-area"> <button type="submit" class="buttons" οnclick="" style="margin-left: 33%">提交</button> </div> </form>
后端:
@app.route('/question/', methods=['GET', 'POST']) @loginFirst def question(): if request.method == 'GET': return render_template('question.html') else: title = request.form.get('title') detail = request.form.get('detail') author_id = User.query.filter(User.username == session.get('user')).first().id # 将session get到的user进行查询并取出id放到外键author_id中 question = Question(title=title, detail=detail, author_id=author_id) db.session.add(question) db.session.commit() return redirect(url_for('shouye')) # 重定向到登录页
8、首页搜索
@app.route('/search/') def search(): qu=request.args.get('q') # args获取关键字,区别form ques=Question.query.filter( or_( # 两种查询条件 Question.title.contains(qu), # contains模糊查 Question.detail.contains(qu) ) ).order_by('-creat_time') return render_template('shouye.html',questions=ques)
9、上下文处理器
@app.context_processor # 上下文处理器,定义变量然后在所有模板中都可以调用,类似idea中的model def mycontext(): usern = session.get('user') if usern: return {'username': usern} # 包装到username,在所有html模板中可调用 else: return {} # 返回空字典,因为返回结果必须是dict
10、跳转页面前登录
def loginFirst(func): @wraps(func) def wrapper(*args, **kwargs): # 定义wrapper函数将其返回,用*args, **kwargs把原函数的参数进行传递 if session.get('user'): # 只有经过登陆,session才能记住并get到值 return func(*args, **kwargs) else: return redirect(url_for('login') return wrapper
11、修改密码
@app.route('/edit_password/', methods=['GET', 'POST']) def edit_password(): if request.method == 'GET': return render_template("edit_password.html") else: newpassword = request.form.get('password') user = User.query.filter(User.id == session.get('userid')).first() #userid与login中的userid是一样的,base.html也是运用到这里的userid user.password = newpassword db.session.commit() return redirect(url_for('shouye'))
12、注销
@app.route('/logout') def logout(): session.clear() return redirect(url_for('base'))
13、 分类
前端:
<form action="{{ url_for('search') }}" class="navbar-form navbar-right" role="search" method="get"> <select class="form-control" name="fenlei" id="fenlei"> <option value="">星类分类</option> <option value="男明星">男明星</option> <option value="女明星">女明星</option> <option value="童星">童星</option> </select> <div class="form-group"><input type="text" name="q" class="form-control" placeholder="输入您感兴趣..."> </div> <button type="submit" class="btn btn-default" style="width: 50px">查询</button>
后端:
@app.route('/search/') def search(): qu=request.args.get('q') # args获取关s键字,区别form fenlei = request.args.get('fenlei') ques=Question.query.filter( and_( # 两种查询条件 Question.title.contains(qu), # 通过模糊查询,查找问题的标题 Question.detail.contains(qu), # 通过模糊查询,查找问题的详细内容 Question.fenlei.contains(fenlei) ) ).order_by('-creat_time') return render_template('shouye.html',questions=ques) # question要和原首页数据模型一样
七、总计和体会
历经十几周的web前端开发的学习后,进步不算大,但也收获不少我的设计当中还是有许多不足,算是低级的,但如果在以后从事相关工作时,我可以借鉴其他人的想法融入自己的设计中,把自己的页面能比较完美的呈现出来。多学会优化自己的网站,多实践和操作,不要小看每次小小的优化,实力都是慢慢积累的。个人觉得“图灵”系列的书籍都是不错的,清晰、透彻,比较适合我们来学习,比如:javascript高级程序设计,精通html与css设计模式等。每个web前台开发工程师都应该具有很强的想象力,发挥想象力,并不断去验证自己的想法才会提高。