Flask 构建微电影视频网站(六)
会员模块实现
会员注册
class RegistForm(FlaskForm):
    name = StringField(
        label="昵称",
        validators=[
            DataRequired("昵称不能为空!")
        ],
        description="昵称",
        render_kw={
            "class": "form-control input-lg",
            "placeholder": "请输入昵称!",
        }
    )
    email = StringField(
        label="邮箱",
        validators=[
            DataRequired("邮箱不能为空!"),
            Email("邮箱格式不正确!")
        ],
        description="邮箱",
        render_kw={
            "class": "form-control input-lg",
            "placeholder": "请输入邮箱!",
        }
    )
    phone = StringField(
        label="手机",
        validators=[
            DataRequired("手机号不能为空!"),
            Regexp("1[34578]\d{9}", message="手机格式不正确!"),
            Length(min=11, max=11, message="手机长度不正确!")
        ],
        description="手机",
        render_kw={
            "class": "form-control input-lg",
            "placeholder": "请输入手机!",
        }
    )
    pwd = PasswordField(
        label="密码",
        validators=[
            DataRequired("密码不能为空!")
        ],
        description="密码",
        render_kw={
            "class": "form-control input-lg",
            "placeholder": "请输入密码!",
        }
    )
    repwd = PasswordField(
        label="确认密码",
        validators=[
            DataRequired("请输入确认密码!"),
            EqualTo('pwd', message="两次密码不一致!")
        ],
        description="确认密码",
        render_kw={
            "class": "form-control input-lg",
            "placeholder": "请输入确认密码!",
        }
    )
    submit = SubmitField(
        '注册',
        render_kw={
            "class": "btn btn-lg btn-success btn-block",
        }
    )
    def validate_name(self, field):
        name = field.data
        user = User.query.filter_by(name=name).count()
        if user == 1:
            raise ValidationError("昵称已经存在!")
    def validate_email(self, field):
        email = field.data
        user = User.query.filter_by(email=email).count()
        if user == 1:
            raise ValidationError("邮箱已经存在!")
    def validate_phone(self, field):
        phone = field.data
        user = User.query.filter_by(phone=phone).count()
        if user == 1:
            raise ValidationError("手机号码已经存在!")
视图函数
@home.route("/regist/", methods=["GET", "POST"])
def regist():
    """
    会员注册
    """
    form = RegistForm()
    if form.validate_on_submit():
        data = form.data
        user = User(
            name=data["name"],
            email=data["email"],
            phone=data["phone"],
            pwd=generate_password_hash(data["pwd"]),
            uuid=uuid.uuid4().hex
        )
        db.session.add(user)
        db.session.commit()
        flash("注册成功!", "ok")
    return render_template("home/regist.html", form=form)
修改对应的前端文件
会员登录
class LoginForm(FlaskForm):
    name = StringField(
        label="账号",
        validators=[
            DataRequired("账号不能为空!")
        ],
        description="账号",
        render_kw={
            "class": "form-control input-lg",
            "placeholder": "请输入账号!",
        }
    )
    pwd = PasswordField(
        label="密码",
        validators=[
            DataRequired("密码不能为空!")
        ],
        description="密码",
        render_kw={
            "class": "form-control input-lg",
            "placeholder": "请输入密码!",
        }
    )
    submit = SubmitField(
        '登录',
        render_kw={
            "class": "btn btn-lg btn-primary btn-block",
        }
    )
视图函数
在登录时需要校验密码,需要在User模型中添加check_pwd函数,和admin模型中的一样
@home.route("/login/", methods=["GET", "POST"])
def login():
    """
    登录
    """
    form = LoginForm()
    if form.validate_on_submit():
        data = form.data
        user = User.query.filter_by(name=data["name"]).first()
        if user:
            if not user.check_pwd(data["pwd"]):
                flash("密码错误!", "err")
                return redirect(url_for("home.login"))
        else:
            flash("账户不存在!", "err")
            return redirect(url_for("home.login"))
        session["user"] = user.name
        session["user_id"] = user.id
        userlog = Userlog(
            user_id=user.id,
            ip=request.remote_addr
        )
        db.session.add(userlog)
        db.session.commit()
        return redirect(url_for("home.user"))
    return render_template("home/login.html", form=form)
在登录时添加登录日志
修改对应的前端文件
修改会员资料
class UserdetailForm(FlaskForm):
    name = StringField(
        label="账号",
        validators=[
            DataRequired("账号不能为空!")
        ],
        description="账号",
        render_kw={
            "class": "form-control",
            "placeholder": "请输入账号!",
        }
    )
    email = StringField(
        label="邮箱",
        validators=[
            DataRequired("邮箱不能为空!"),
            Email("邮箱格式不正确!")
        ],
        description="邮箱",
        render_kw={
            "class": "form-control",
            "placeholder": "请输入邮箱!",
        }
    )
    phone = StringField(
        label="手机",
        validators=[
            DataRequired("手机号不能为空!"),
            Regexp("1[34578]\d{9}", message="手机格式不正确!"),
            Length(min=11, max=11, message="手机长度不正确!")
        ],
        description="手机",
        render_kw={
            "class": "form-control",
            "placeholder": "请输入手机!",
        }
    )
    face = FileField(
        label="头像",
        validators=[
            DataRequired("请上传头像!")
        ],
        description="头像",
    )
    info = TextAreaField(
        label="简介",
        validators=[
            DataRequired("简介不能为空!")
        ],
        description="简介",
        render_kw={
            "class": "form-control",
            "rows": 10
        }
    )
    submit = SubmitField(
        '保存修改',
        render_kw={
            "class": "btn btn-success",
        }
    )
视图函数
修改文件名
def change_filename(filename):
    """
    修改文件名称
    """
    fileinfo = os.path.splitext(filename)
    filename = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + \
               str(uuid.uuid4().hex) + fileinfo[-1]
    return filename
def user_login_req(f):
    """
    登录装饰器
    """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if "user" not in session:
            return redirect(url_for("home.login", next=request.url))
        return f(*args, **kwargs)
    return decorated_function
@home.route("/user/", methods=["GET", "POST"])
@user_login_req
def user():
    form = UserdetailForm()
    user = User.query.get(int(session["user_id"]))
    form.face.validators = []
    if request.method == "GET":
        # 赋初值
        form.name.data = user.name
        form.email.data = user.email
        form.phone.data = user.phone
        form.info.data = user.info
    if form.validate_on_submit():
        data = form.data
        if form.face.data != "":
            file_face = secure_filename(form.face.data.filename)
            if not os.path.exists(app.config["FC_DIR"]):
                os.makedirs(app.config["FC_DIR"])
                os.chmod(app.config["FC_DIR"], 6)
            user.face = change_filename(file_face)
            form.face.data.save(app.config["FC_DIR"] + user.face)
        name_count = User.query.filter_by(name=data["name"]).count()
        if data["name"] != user.name and name_count == 1:
            flash("昵称已经存在!", "err")
            return redirect(url_for("home.user"))
        email_count = User.query.filter_by(email=data["email"]).count()
        if data["email"] != user.email and email_count == 1:
            flash("邮箱已经存在!", "err")
            return redirect(url_for("home.user"))
        phone_count = User.query.filter_by(phone=data["phone"]).count()
        if data["phone"] != user.phone and phone_count == 1:
            flash("手机已经存在!", "err")
            return redirect(url_for("home.user"))
        # 保存
        user.name = data["name"]
        user.email = data["email"]
        user.phone = data["phone"]
        user.info = data["info"]
        db.session.add(user)
        db.session.commit()
        flash("修改成功!", "ok")
        return redirect(url_for("home.user"))
    return render_template("home/user.html", form=form, user=user)
在初始化文件中添加app.config["FC_DIR"] = os.path.join(os.path.abspath(os.path.dirname(__file__)), "static/uploads/users/")
修改对应的前端文件
修改密码
class PwdForm(FlaskForm):
    old_pwd = PasswordField(
        label="旧密码",
        validators=[
            DataRequired("旧密码不能为空!")
        ],
        description="旧密码",
        render_kw={
            "class": "form-control",
            "placeholder": "请输入旧密码!",
        }
    )
    new_pwd = PasswordField(
        label="新密码",
        validators=[
            DataRequired("新密码不能为空!"),
        ],
        description="新密码",
        render_kw={
            "class": "form-control",
            "placeholder": "请输入新密码!",
        }
    )
    submit = SubmitField(
        '修改密码',
        render_kw={
            "class": "btn btn-success",
        }
    )
视图函数
@home.route("/pwd/", methods=["GET", "POST"])
@user_login_req
def pwd():
    """
    修改密码
    """
    form = PwdForm()
    if form.validate_on_submit():
        data = form.data
        user = User.query.filter_by(name=session["user"]).first()
        if not user.check_pwd(data["old_pwd"]):
            flash("旧密码错误!", "err")
            return redirect(url_for('home.pwd'))
        user.pwd = generate_password_hash(data["new_pwd"])
        db.session.add(user)
        db.session.commit()
        flash("修改密码成功,请重新登录!", "ok")
        return redirect(url_for('home.logout'))
    return render_template("home/pwd.html", form=form)
修改对应的前端文件
会员登录日志
登陆日志不需要表单
@home.route("/loginlog/<int:page>/", methods=["GET"])
@user_login_req
def loginlog(page=1):
    """
    会员登录日志
    """
    if page <= 0:
        page = 1
    page_data = Userlog.query.filter_by(
        user_id=int(session["user_id"])
    ).order_by(
        Userlog.addtime.desc()
    ).paginate(page=page, per_page=10)
    return render_template("home/loginlog.html", page_data=page_data)
新建app/templates/ui/home_page.html,用来分页
{% macro page(data,url) -%}
    {% if data %}
        <nav aria-label="Page navigation">
            <ul class="pagination">
                <li><a href="{{ url_for(url,page=1) }}">首页</a></li>
                {% if data.has_prev %}
                    <li><a href="{{ url_for(url,page=data.prev_num) }}">上一页</a></li>
                {% else %}
                    <li class="disabled"><a href="#">上一页</a></li>
                {% endif %}
                {% for v in data.iter_pages() %}
                    {% if v %}
                        {% if v == data.page %}
                            <li class="active"><a href="#">{{ v }}</a></li>
                        {% else %}
                            <li><a href="{{ url_for(url,page=v) }}">{{ v }}</a></li>
                        {% endif %}
                    {% endif %}
                {% endfor %}
                {% if data.has_next %}
                    <li><a href="{{ url_for(url,page=data.next_num) }}">下一页</a></li>
                {% else %}
                    <li class="disabled"><a href="#">下一页</a></li>
                {% endif %}
                <li><a href="{{ url_for(url,page=data.pages) }}">尾页</a></li>
            </ul>
        </nav>
    {% endif %}
{%- endmacro %}
修改对应的前端代码,并使用这个分页
Flask 构建微电影视频网站(六)的更多相关文章
- Python flask 构建微电影视频网站☝☝☝
		Python flask 构建微电影视频网站☝☝☝ 1.安装数据库连接依赖包 pip install flask-sqlalchemy 2.创建movie数据库 在CentOS虚拟机,进入MaridD ... 
- Python flask 构建微电影视频网站✍✍✍
		Python flask 构建微电影视频网站 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大 ... 
- Flask 构建微电影视频网站(一)
		Flask构建电影视频网站 Python MTV模型 Flask微内核 Flask扩展插件配置及使用方法 根据业务开发网站前后台功能 Flask结合MySQL数据库 你将可以独立开发网站 独立部署运维 ... 
- Python Flask 构建微电影视频网站
		前言 学完本教程,你将掌握: 1.学会使用整形.浮点型.路径型.字符串型正则表达式路由转化器 2.学会使用post与get请求.上传文件.cookie获取与相应.404处理 3.学会适应模板自动转义. ... 
- Flask 构建微电影视频网站(四)
		后台管理 实现后台管理系统使用flask sqlalchemy结合mysql数据库进行增删改查操作.分页的使用.路由装饰器定义.模板中变量调用.登录会话机制.上传文件.flask wtforms表单使 ... 
- Flask 构建微电影视频网站(二)
		搭建前台页面 前台布局搭建 将static中的文件拷贝到项目的static目录下 在app/templates/home下新建home.html,当作基础模板,并修改静态资源链接 <!docty ... 
- Flask 构建微电影视频网站(八)
		评论收藏及弹幕 实现电影评论添加及列表.数据查询实现统计播放量和评论量.jquery ajax实现收藏电影,flask结合redis消息队列实现电影弹幕,bug处理等功能. 电影评论-统计 class ... 
- Flask 构建微电影视频网站(三)
		搭建后台页面 视图函数位于admin文件夹下, app/admin/views.py 管理员登录页面搭建 视图函数 @admin.route('/') def index(): return '后台主 ... 
- Flask 构建微电影视频网站(七)
		电影模块实现 上映预告 @home.route("/animation/") def animation(): """ 首页轮播动画 "&q ... 
随机推荐
- 用VS2017进行移动开发(C#、VB.NET)——Progress控件,Smobiler移动开发
			Progress控件 一. 样式一 我们要实现上图中的效果,需要如下的操作: 从工具栏上的“Smobiler Components”拖动一个Progress控件到窗体界面上 修改Pr ... 
- ado.net的简单数据库操作(二)之封装SqlHelperl类
			今天我书接上回,接着昨天的ado.net的数据库操作的相关知识来讲哈! 从上篇文章给出的实例来看,你一定会发现,操作数据库其实还挺麻烦的,就连一个最简单的数据库操作语句都要包括 定义数据库连接字符串. ... 
- 基于vue.js的简单用户管理
			功能描述:添加.修改.搜索过滤 效果图: <!DOCTYPE html> <html lang="en"> <head> <title&g ... 
- Form 表单提交的几种方式
			简单的总结一下form表单提交的几种方式:1.最简单的方式 就用form的submit提交方式,这种提交方式是不需要回调函数的 这种方式最近到一个form提供action路径后台接受就可以< ... 
- 在线生成二维码的API接口
			现在很多大网站都有这样的一个功能,使用手机扫描一下网页上的二维码便可快速在手机上访问网站.想要实现这样的功能其实很简单,下面麦布分享几个在线生成网址二维码的API接口.都是采用http协议接口,无需下 ... 
- 05 入门 - 浅谈 ASP.NET MVC程序的工作原理
			目录索引:<ASP.NET MVC 5 高级编程>学习笔记 本篇内容 1. Global.asax文件 2. RouteConfig.cs文件 3. 视图命名和寻址的规则 前面创建了一个简 ... 
- JQuery拖拽元素改变大小尺寸
			<!DOCTYPE html><html> <head> <title></title> <style type="text ... 
- Numpy库的学习(一)
			今天来学习一下Python库中,支持高级大量的维度数组与矩阵运算的神奇的Numpy库 Numpy同时也对数组运算提供大量的数学函数,对于大量计算运行效率极好 是大量机器学习框架的基础库 废话不多说,直 ... 
- ASP.NETMVC 分页
			<div class="text-center"> <span style="display:inline-block; position:re ... 
- Linux学习历程——SUID、SGID、SBIT简介
			一.SUID.SGID.SBIT简介 SUID:对一个可执行文件,不是以发起者身份来获取资源,而是以可执行文件的属主身份来执行.SGID:对一个可执行文件,不是以发起者身份来获取资源,而是以可执行文件 ... 
