美文网首页
Flask 构建微电影视频网站(6)

Flask 构建微电影视频网站(6)

作者: 听你讲故事啊 | 来源:发表于2018-12-01 11:31 被阅读0次

    会员模块实现

    会员注册

    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 构建微电影视频网站(6)

          本文链接:https://www.haomeiwen.com/subject/gdblcqtx.html