沿用Python+Flask+Mysql的web建设技术开发网站

1 系统概要说明

1.1 开发目的

闲暇时光想看看电影?我要看些什么好呢?百度推荐出来的烂片也不在其数,如果有一个真实反映影片的平台该多好,这就是淘智宝的产生,为电影连续剧爱好人群提供一个可以自由言论的平台,我喜欢的电影我可以发上去,看看别人是否也会喜欢,综合评价下来,影视爱好者一定能收获自己最想看的年度好片。

好片是千人的智慧产生,而不掺杂广告票房目的,如果我们都看过这部片,评论区交流一下一拍即合,也许我们能够成为好朋友呢?我看你的个人中心你喜欢的电影我都看过,我们是不是就有说不完的话题了呢?

1.2 需求分析

那么首先,我们需要注册一个用户,用户名和密码的长度6-12位为宜,注册用户后我们需要登录上去,最好是去个人中心上传你的头像,让更多人注意到你,然后,就可以开始发布一篇新影评了,发布上去后,根据时间的排序,你的影评很快就会被人看到,他们评论了你的影评,也觉得这部电影很好,就会收藏到收藏夹,下次想看电影的时候翻出来看看,或者是给你点了个赞,但是还没有特别的喜欢,可能只是你的影评写的不错。为了账户的安全,我们还可以去个人中心定期修改一下密码,觉得最近的自拍照很好看,也可以更换头像让大家看到。

如果我只是一名游客,我不想注册新用户,那么我可以去排行榜看看大家到底喜欢什么电影,如果还是看不出来,我可以去详情页下载电子书剧情介绍,觉得不错再去电影院看。每个人都有自己喜欢的电影类型,可以按分类筛选,如果游客对一部电影早有耳闻,只想看看评价,那么在搜索框模糊搜索电影的名字,或者主人公的名字,都能够搜索出来。

2 网站结构设计

2.1 结构分析

2.2 开发方案及使用技术

目前市场流行影视网站网站,用户都可以在上面与一起观看该电影的人分享自己的看法,对于平台上,更多的数据不是我们产生,而是用户的上网行为影响到自己所看的内容,我们称之为人机交互,也就是我们现在所说的WEB2.0开发模式。

前端框架,使用的是DIV+CSS的布局,同时使用了AJAX技术,提高了用户的体现。

后端框架,使用的是Python的Flask框架,这是一款累轻量框架。适合开发中小型系统,并且可以快速开发。

2.3 功能用法分析

首页主要包括:

1)     热门文章。给用户推荐平台上,点击数量最大的前五本书,让用户可以了解大家都喜欢什么样的书。

2)     文章列表。每一本书的标题、时间、作者、分享还有简介的摘要也会以一条条的形式显示在首页,而且每一秒都会显示再新的分享,图片展示方式更容易吸引眼球。

3)     高级搜索。单一的搜索只能找到书中有过的关键字,高级搜索可以将多个条件同时录入进行搜索。

4)     文章分类。以类别分别显示文章列表。

5)     注册。新用户注册平台账号。

6)     登陆。登录账号去管理个人中心中的个人信息。

7)     排行版:查看最近都有哪些热门电影,越多人喜欢的电影你肯定也会喜欢。

详情页是指文章点进去后,显示文章内容的页面,其中还包括以下:

1)     推荐文章。推荐你喜欢的文章。

2)     评论。表达用户对这篇文章的看法。

3)     点赞。觉得写的好,就点个赞吧。

4)     收藏。把你认为好的,以后还会看收藏起来,在我的个人中心,以后还可以点开来看。

5)     下载。下载电子书,剧情先知道。

对于有以登录的用户,平台还提供了个人中心去管理自己的信息:

1)     上传头像。用户可以自定义自己的头像,默认是一个黑色的头像,上传有自己个性的头像,可以让别人更加容易记得自己。

2)     修改密码。为了账号安全,定期修改密码。

3)     我的收藏。把你认为好的,以后还会看收藏起来,在我的个人中心,以后还可以点开来看。

4)     我的发布。自己曾经发布过的文章可以再次打开的看,也可以有不对的地方再次编辑。

5)     我的评论。你对别人的评论,可以在这里看到,也可删除你认为说法有误的评论。

3 模块详细设计

3.1 注册

# 注册

@app.route(‘/register/‘, methods=[‘GET‘, ‘POST‘])

def register():

if request.method
== ‘GET‘:

return render_template(‘register.html‘)

else:

username = request.form.get(‘username‘)

password = request.form.get(‘password‘)

say = request.form.get(‘say‘)

user =
User.query.filter(User.username == username).first()

# 判断用户名是否存在

if user:

return u‘
username existed‘

else:

user = User(username=username, password=password, say=say)

db.session.add(user)

db.session.commit()

return redirect(url_for(‘login‘))

3.2 登录

# 登录

@app.route(‘/login/‘, methods=[‘GET‘, ‘POST‘])

def login():

    if request.method == ‘GET‘:

        return render_template(‘denglu.html‘)

    else:

        usern = request.form.get(‘username‘)

        passw = request.form.get(‘password‘)

        user = User.query.filter(User.username == usern).first()

        # 判断用户名是否存在

        if user:

            if user.check_password(passw):

                session[‘user‘] = usern  # 字典键值

                session[‘userid‘] = user.id

                session.permanent = True

                return redirect(url_for(‘index‘))

            else:

                return u‘ password error‘

        else:

            return u‘ username  not existed‘

# 判断是否登陆,有则在导航栏显示用户名

@app.context_processor

def mycontext():

    usern = session.get(‘user‘)

    user = User.query.filter(User.username == usern).first()

    if usern:

        return {‘username‘: usern, ‘user‘: user}

    else:

        return {}

# 登出,清除session

@app.route(‘/logout‘)

def logout():

    session.clear()

    return redirect(url_for(‘index‘))

3.3 发布



# 发布前登陆装饰器

def loginFirst(func):  # 参数是函数

    @wraps(func)

    def wrapper(*args, **kwargs):  # 定义个函数将其返回

        if session.get(‘user‘):

            return func(*args, **kwargs)

        else:

            return redirect(url_for(‘login‘))

    return wrapper  # 返回一个函数
#发布问答
1.编写要求登录的装饰器

from functools import wraps

def loginFirst(func): #参数是函数

@wraps(func)

      def wrapper(*args, ** kwargs): #定义个函数将其返回

          #要求登录

          return func(*args, ** kwargs)

      return wrapper #返回一个函数

2.应用装饰器,要求在发布前进行登录,登录后可发布。

@app.route(‘/question/‘,methods=[‘GET‘,‘POST‘])
@loginFirst
def question():

#发布前登陆装饰器

def loginFirst(func):  # 参数是函数

    @wraps(func)

    def wrapper(*args, **kwargs):  # 定义个函数将其返回

        if session.get(‘user‘):

            return func(*args, **kwargs)

        else:

            return redirect(url_for(‘login‘))

    return wrapper  # 返回一个函数

3.建立发布内容的对象关系映射。

class Question(db.Model):

4.完成发布函数。

  保存到数据库。

  重定向到首页。

#登陆前验证,进入评论进入问答页

@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

        question = Question(title=title, detail=detail, author_id=author_id)

        db.session.add(question)

db.session.commit()


return redirect(url_for(‘index‘))

 

3.4 条件组合搜索

# 查找
@app.route(‘/search/‘)
def search():
    qu = request.args.get(‘q‘)
    c = ‘‘ if request.args.get(‘classflyList‘) == None else request.args.get(‘classflyList‘)
    t = ‘-creat_time‘ if request.args.get(‘creat_time‘) == None else ‘creat_time‘ if request.args.get(
        ‘creat_time‘) == ‘0‘ else ‘-creat_time‘
    y = ‘‘ if request.args.get(‘year‘) == None else request.args.get(‘year‘)
    ques = Question.query.filter(
        or_(
            Question.xiazai.contains(qu), Question.detail.contains(qu)
        ),
        Question.classify.like(‘%‘ + c + ‘%‘),
        Question.creat_time.like(‘%‘ + y + ‘%‘),
    ).order_by(t).all()
    return render_template(‘index.html‘, questions=ques)
# 高级查询
@app.route(‘/highSearch/‘)
def highSearch():
    if request.args.get(‘click‘):  # 判断get请求中是否有这个变量传入值
        click = request.args.get(‘click‘)  # basic.html中获取click的限定条数
        ques = Question.query.filter(
            Question.click >= click
        ).order_by(‘-creat_time‘)
        # 如果该问题点赞数大于click中指定的数字,则查找出来,放到ques,并把ques赋值给questions(全部问答显示的列表)显示出来
        return render_template(‘index.html‘, questions=ques)

    if request.args.get(‘comment‘):  # 判断get请求中是否有这个变量传入值
        comment = request.args.get(‘comment‘)  # basic.html中获取comment的限定条数
        com = Question.query.all()  # 获取Question表中的所有问答信息,存到com
        result = []  # 定义一个空列表result
        for qu in com:  # 如果每一个问答信息中的总评论数大于comment中的评论数,就把内容增加到result列表中
            if len(qu.comment) >= int(comment):
                result.append(qu)
                # 把列表内容赋值给questions
        return render_template(‘index.html‘, questions=result)

3.5 收藏

# 收藏
@app.route(‘/col‘, methods=[‘GET‘, ‘POST‘])
@loginFirst
def col():
    user = User.query.filter(User.id == session.get(‘userid‘)).first()
    context = {
        ‘questions‘: user.collection.all(),
        ‘tj‘: Question.query.all()[0:5],
    }

    return render_template(‘collect.html‘, **context)

3.6 修改密码

# 修改密码
@app.route(‘/setPassword/<user_id>‘, methods=[‘GET‘, ‘POST‘])
@loginFirst
def setPassword(user_id):
    if request.method == ‘GET‘:
        if request.args.get(‘info‘):
            info = request.args.get(‘info‘)
        else:
            info = None
        return render_template(‘editPassword.html‘,info=info)
    else:
        user = User.query.filter(User.id == user_id).first()
        if user:
            if user.check_password(request.form.get(‘old‘)):
                user.password = request.form.get(‘new1‘)
                db.session.commit()
                info = ‘修改成功‘
            else:
                info = ‘原密码错误‘
                return redirect(url_for(‘setPassword‘,user_id=user_id,info=info))
        else:
            info = ‘未知错误‘
        return redirect(url_for(‘personcenter‘, user_id=user_id, info=info))

3.7 上传头像

#上传头像
@app.route(‘/uploadLogo/<user_id>‘, methods=[‘GET‘, ‘POST‘])
def uploadLogo(user_id):
    user = User.query.filter(User.id == user_id).first()
    edimg = request.files[‘edimg‘]
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    upload_path = os.path.join(basepath, ‘static/uploads‘, edimg.filename)  # 注意:没有的文件夹一定要先创建,不然会提示没有该路径
    edimg.save(upload_path)
    user.image = ‘uploads/‘ + edimg.filename
    db.session.commit()
    return redirect(url_for(‘personcenter‘, user_id=user_id));

3.8 评论

# 登陆前验证,进入评论进入问答页
@app.route(‘/question/‘, methods=[‘GET‘, ‘POST‘])
@loginFirst
def question():
    if request.method == ‘GET‘:
        return render_template(‘question.html‘)
    else:
        xiazai = request.form.get(‘xiazai‘)
        title = request.files[‘title‘]
        basepath = os.path.dirname(__file__)  # 当前文件所在路径
        upload_path = os.path.join(basepath, ‘static/fengmian‘, title.filename)  # 注意:没有的文件夹一定要先创建,不然会提示没有该路径
        title.save(upload_path)  # 存进服务器
        detail = request.form.get(‘detail‘)
        author_id = User.query.filter(User.username == session.get(‘user‘)).first().id
        classify = request.form.get(‘classify‘)
        question = Question(title=‘http://127.0.0.1:5000/static/fengmian/‘ + title.filename, xiazai=xiazai, detail=detail, author_id=author_id, classify=classify)
        # question.author=author_id
        db.session.add(question)
        db.session.commit()
        return redirect(url_for(‘index‘))

4 数据库设计

4.2 程序模型现实

# 收藏表
Collection = db.Table(
    ‘collection‘,
    db.Column(‘id‘, db.Integer, primary_key=True, autoincrement=True),
    db.Column(‘q‘, db.Integer, db.ForeignKey(‘question.id‘)),  # 评论对应的文章的id
    db.Column(‘u‘, db.Integer, db.ForeignKey(‘user.id‘)),  # 收藏用户的id
)

#用户表
class User(db.Model):
    __tablename__ = ‘user‘
    # 建立一个表user
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(20), nullable=False)
    _password = db.Column(db.String(200), nullable=False)
    image = db.Column(db.String(100), default=‘uploads/default_logo.jpg‘)
    say = db.Column(db.String(50))
    collection = db.relationship(‘Question‘, secondary=Collection, backref=db.backref(‘user‘, lazy=‘dynamic‘),
                                 lazy=‘dynamic‘)

    @property
    def password(self):  # 外部使用
        return self._password

    @password.setter
    def password(self, row_password):
        self._password = generate_password_hash(row_password)

    def check_password(self, row_password):
        result = check_password_hash(self._password, row_password)
        return result

# 建立一表question
class Question(db.Model):
    __tablename__ = ‘question‘

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(100), nullable=False)
    detail = db.Column(db.Text, nullable=False)
    xiazai = db.Column(db.Text, nullable=False)
    creat_time = db.Column(db.DateTime, default=datetime.now)
    author_id = db.Column(db.Integer, db.ForeignKey(‘user.id‘))
    author = db.relationship(‘User‘, backref=db.backref(‘question‘))
    classify = db.Column(db.Enum(‘都市言情‘, ‘青春校园‘, ‘古装玄幻‘, ‘悬疑惊悚‘), nullable=False)
    click = db.Column(db.INT, default=0)

# 评论表

class Comment(db.Model):
    __tablename__ = ‘comment‘
    # 建立一个表log
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    author_id = db.Column(db.Integer, db.ForeignKey(‘user.id‘))
    question_id = db.Column(db.Integer, db.ForeignKey(‘question.id‘))
    creat_time = db.Column(db.DateTime, default=datetime.now)
    detail = db.Column(db.Text, nullable=False)
    question = db.relationship(‘Question‘, backref=db.backref(‘comment‘, order_by=creat_time.desc))
    author = db.relationship(‘User‘, backref=db.backref(‘comment‘))

5 系统实现的关键算法与数据结构

5.1  背景开关灯的实现

运行JavaScript代码,添加点击事件,来响应并改变背景的CSS样式,则达到开关灯的功能。

function mySwitch() {
    var oBody = document.getElementById("myBody");
    var ogood = document.getElementById("mygood");
    var oOnOff = document.getElementById("myOnOff");

    if (oOnOff.src.match(‘bulbon‘)) {

        oOnOff.src = "http://www.runoob.com/images/pic_bulboff.gif";
        oBody.style.backgroundColor = "black";

        oBody.style.color = "white";
         ogood.style.display="none";
    } else {
        oOnOff.src = "http://www.runoob.com/images/pic_bulbon.gif";
        oBody.style.backgroundColor = "white";
        oBody.style.color = "black";

         ogood.style.display="block";

    }
}

5.2  图片与文件的上传下载实现

一键下载电子书,以txt文件形式保存到你的电脑,更方便快捷下次查看

    <span style="width:300px;float:left;margin-top: 230px;margin-left:-235px">电子书下载: <input id="fat-btn"
                                                                                          class="btn btn-default"
                                                                                        type="button"
                                                                                        value=‘Download‘
                                                                                        onclick="location.href=‘{{ url_for(‘download‘,filename=‘static‘,question_id=ques.xiazai) }}‘"></span>
# 下载
@app.route(‘/<filename>/<question_id>‘)
def download(filename, question_id):
    quest = Question.query.filter(Question.id == question_id).first()  # 从Question表查找出对应的问答id
    context = {
        ‘questions‘: Question.query.order_by(‘-creat_time‘).all()

    }

    return render_template(‘detail.html‘, **context, ques=quest)

上传头像,让他人更好的认识你

# 上传头像
@app.route(‘/uploadLogo/<user_id>‘, methods=[‘GET‘, ‘POST‘])
def uploadLogo(user_id):
    user = User.query.filter(User.id == user_id).first()
    edimg = request.files[‘edimg‘]
    basepath = os.path.dirname(__file__)  # 当前文件所在路径
    upload_path = os.path.join(basepath, ‘static/uploads‘, edimg.filename)  # 注意:没有的文件夹一定要先创建,不然会提示没有该路径
    edimg.save(upload_path)
    user.image = ‘uploads/‘ + edimg.filename
    db.session.commit()
    return redirect(url_for(‘personcenter‘, user_id=user_id));

5.3  修改密码提示

# 修改密码
@app.route(‘/setPassword/<user_id>‘, methods=[‘GET‘, ‘POST‘])
@loginFirst
def setPassword(user_id):
    if request.method == ‘GET‘:

        if request.args.get(‘info‘):
            info = request.args.get(‘info‘)
        else:
            info = None
        return render_template(‘editPassword.html‘,info=info)
    else:
        user = User.query.filter(User.id == user_id).first()
        if user:
            if user.check_password(request.form.get(‘old‘)):
                user.password = request.form.get(‘new1‘)
                db.session.commit()
                info = ‘修改成功‘
            else:
                info = ‘原密码错误‘
                return redirect(url_for(‘setPassword‘,user_id=user_id,info=info))
        else:
            info = ‘未知错误‘
        return redirect(url_for(‘personcenter‘, user_id=user_id, info=info))

 页面中:通过定义info提示框实现在后台应用js代码

<script>
    {% if info %}
        alert(‘{{ info }}‘)
    {% endif %}
</script>

6 成品展示

1网站父模板统一布局

2注册、登录、注销

点击注销,呈现的内容不一样,收藏夹需要登录前验证

3.发布引用编辑插件、影评列表div+css显示

4.详情页

夜晚开启护眼模式:

5.评论、列表显示

6.个人中心

我对这个作者有兴趣,我想看看她的资料(用户中心):

7.搜索,条件组合搜索

Eg:这是点赞数10以上、评论2以上的

8.文章分类、显示(古装玄幻类为例)

9点赞、收藏

Eg:点了个赞变成27:

Eg:没收藏的时候是这样的:

Eg:收藏后是这样的:

 

10修改密码、头像、上传头像

上传头像和预览如下:

 

觉得可以就点击upload就换好头像

11我的发布、点赞、收藏、评论

我发过的影评在这里(可删除自己的影评):

我发过的评论在这里(可删除自己的评论):

收藏过的影评:

12高级搜索

可同时按分类按时间排序:

13热门文章、推荐文章

推荐的作品在详情页可以看到:

热门的作品在排行榜可以看到:

14下载文件

点击电子书下载,可以下载到我的电脑

 

原文地址:https://www.cnblogs.com/decadeyu/p/9188391.html

时间: 2024-11-09 06:23:33

沿用Python+Flask+Mysql的web建设技术开发网站的相关文章

Python+Flask+MysqL的web建设技术开发一个网站

一.摘要 flask是一个很精简,灵活的框架,对于web的开发非常的好,具有jinja2强大的模板引擎的支持.flask框架的一个扩展就是sqlalchemy, sqlalcheny是flask的一个扩展.sqlalcheny是一个强大的关系型数据库框架,它是一个框架,并不是数据库.sqlalcheny数据库的操作得益于我们的ORM技术,将繁琐的数据库操作转化为我们的python的类,其实还是转化为sql语句来操作数据库,这就是他的强大的地方,同时特提供了数据库原生的SQL底存功能.sqlalc

Python+Flask+MysqL的web建设技术过程

前言 本人在一学期时间实现了Python+Flask+MysqL的web建设,页面具有简单的登录注册发布文章搜索文章等功能. 这篇文章总结了我最近一段时间的学习成果:使用Flask框架搭建一个web service,并在其中加上一些简单的css,js,html等.在本文中以实际的用户模块为例.之所以写这篇文章是因为想要总结自己一学期的学习成果并且与大家分享.由于是新手如有错漏请见谅. 一.使用工具 python3.5 实现此页面所有的static文件.templates文件与py文件 二.完成基

用ASP.NET Web API技术开发HTTP接口(一)

开发工具 Visual Studio 2013 SQL Server 2008 R2 准备工作 启动Visual Studio 2013,新建一个ASP.NET Web应用程序,命名为SimpleAPI.选择Empty模板,并勾选"Web API",无身份验证,不添加单元测试. 准备用SQL Server数据库来存储数据,因此要安装下Entity Framework框架,免去写繁琐SQL语句的麻烦.打开工具->程序包管理器控制台输入以下命令安装. Install-Package

WEB系统技术开发方向

1. UI框架:要可以结合jquery+自定义服务器控件开发一套UI框架: 2.WEB报表设计器:用js开发一套可以自定义报表设计器: 3.WEB自定义表单+工作流设计器: 4.WEB打印组件: 5.通用权限管理系统: 6.ORM:自己封装一套高效的ORM工具: 7.单点登陆及状态管理.网站皮肤切换.语言管理.缓存管理.Cookie管理: 8.全文检索: 9.日志平台: 10.WCF服务+IOC+各种模式

Python Flask+Bootstrap+Jinja2 构建轻量级企业内部系统平台框架

1.最近公司运维需求,学习python flask 满足环境治理系统的开发;入门如下;    环境类型:      Python 2.7.5         获取地址:https://www.python.org/downloads/       Flask  1.0.2               pip 安装使用模快如下:           flask==1.0.2           request==1.0.2           Jinja2==2.10           Flas

Python Flask+Gentelella+Jinja2 快速完成企业内部系统平台快速布局;

1.最近公司运维需求,学习python flask 满足环境治理系统的开发 原生前端Bootstrap 也能满足需求,但是需要前端功基本功(html,css,js)等,折腾了2周发现 实在是太麻烦: 而且布局样式特别low 很难看 各种 按钮和样式效果实现特麻烦(哈哈,原谅我初学者吐槽下,Bootstrap 社区开发人别喷我,谢谢) 2.githup 意外发现一个 gentelella 这套后台模板; (非常强大和适用且美观,不用说立马拿下;) 源码获取地址:https://github.com

Python Flask 向MySQL表里插入一条记录,提示Unknown column &#39;XXX&#39; in &#39;field list

sql =' INSERT INTO `blog`.`user` (`id`, `username`) VALUES (%d, %s)' %(1,username) 我在给username赋值aaabbb后提示:"Unknown column 'aaaabbb' in 'field list'" 找了半天问题,原来是%s没加双引号. 改为如下 sql =' INSERT INTO `blog`.`user` (`id`, `username`) VALUES (%d, "%s

Python Flask 快速构建高性能大型web网站项目实战

Python Flask 快速构建高性能大型web网站项目实战视频[下载地址:https://pan.baidu.com/s/1cUggNbUvptYz5vvwBhsdrg ] 作为最最流行的Python Web开发的微框架,Flask独树一帜.它不会强迫开发者遵循预置的开发规范,为开发者提供了自由度和创意空间.突然发现这个对自动化运维开发非常有用,发上来,给大家! Python Flask 快速构建高性能大型web网站项目实战视频 project.zip 第1章 课程介绍1.1-1.2课程导学

Python Flask框架——全栈开发(知了课堂)

章节1:Flask视图和URL 课时1[虚拟环境]为什么需要虚拟环境06:28 课时2[虚拟环境]virtualenv创建虚拟环境13:55 课时3[虚拟环境]virtualenvwrapper使用16:42 课时4[Flask预热]课程介绍45:34 课时5[Flask预热]Flask课程准备工作11:30 课时6[Flask预热]URL组成部分详解14:02 课时7[Flask预热]web服务器+应用服务器+web应用框架14:16 课时8[Flask URL]第一个flask程序详解24: