Flask项目之个性化微电影网站的实战开发(完结)

本博客详细介绍了使用Flask开发个性化微电影网站的过程,涵盖会员注册登录、电影模块、评论及统计、收藏功能、弹幕播放等。内容包括前端管理的各项功能实现,如会员信息修改、电影搜索、评论分页显示、收藏电影等,并对代码进行了优化和bug处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

接着上一篇博客继续往下写 :Flask项目之个性化微电影网站的实战开发(三)_cdtaogang's blog-优快云博客

非VIP用户请点击这里进行查阅

目录

一丶前台管理(会员模块)

二丶前台管理(电影模块)

三丶前台管理(电影评论及统计)

四丶前台管理(电影收藏)

五丶前台管理(电影弹幕)

六丶代码优化以及bug处理


一丶前台管理(会员模块)

1.会员注册

  • 定义会员注册表单
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[345789]\\d{9}", 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("手机号码已经存在!")
  • 填写模板数据
<form novalidate role="form" method="post">
    <fieldset>
        <div class="form-group">
            <label for="input_name"><span class="glyphicon glyphicon-user"></span>&nbsp;{
  
  {form.name.label}}</label>
            {
  
  {form.name}}
            {% for error in form.name.errors %}
            <div class="col-md-12">
                <p style="color:red">{
  
  { error }}</p>
            </div>
            {% endfor %}
        </div>
        <div class="col-md-12" id="error_name"></div>
        <div class="form-group">
            <label for="input_email"><span class="glyphicon glyphicon-envelope"></span>&nbsp;{
  
  {form.email.label}}</label>
            {
  
  {form.email}}
            {% for error in form.email.errors %}
            <div class="col-md-12">
                <p style="color:red">{
  
  { error }}</p>
            </div>
            {% endfor %}
        </div>
        <div class="col-md-12" id="error_email"></div>
        <div class="form-group">
            <label for="input_phone"><span class="glyphicon glyphicon-phone"></span>&nbsp;{
  
  {form.phone.label}}</label>
            {
  
  {form.phone}}
            {% for error in form.phone.errors %}
            <div class="col-md-12">
                <p style="color:red">{
  
  { error }}</p>
            </div>
            {% endfor %}
        </div>
        <div class="col-md-12" id="error_phone"></div>
        <div class="form-group">
            <label for="input_password"><span class="glyphicon glyphicon-lock"></span>&nbsp;{
  
  {form.pwd.label}}</label>
            {
  
  {form.pwd}}
            {% for error in form.pwd.errors %}
            <div class="col-md-12">
                <p style="color:red">{
  
  { error }}</p>
            </div>
            {% endfor %}
        </div>
        <div class="col-md-12" id="error_password"></div>
        <div class="form-group">
            <label for="input_repassword"><span class="glyphicon glyphicon-lock"></span>&nbsp;{
  
  {form.repwd.label}}</label>
            {
  
  {form.repwd}}
            {% for error in form.repwd.errors %}
            <div class="col-md-12">
                <p style="color:red">{
  
  { error }}</p>
            </div>
            {% endfor %}
        </div>
        <div class="col-md-12" id="error_repassword"></div>
        {
  
  {form.submit}}
        {
  
  {form.csrf_token}}
    </fieldset>
</form>
  • 定义视图函数
# 会员注册
@home.route('/register/', methods=['GET', 'POST'])
def register():
    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/register.html",form=form)
  • 测试会员注册功能

2.会员登录以及退出

会员登录

  • 定义登录表单
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",
        }
    )
  • 定义登录视图函数
# 会员登录
@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 not user.check_pwd(data['pwd']):
            flash("密码错误!", "err")
            return redirect(url_for('home.login'))
        # 将登录成功后的用户名以及用户id保存到session会话机制中
        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)
  • 填写模板数据
<form novalidate role="form" method="post">
    <fieldset>
        <div class="form-group">
            <label for="input_contact"><span class="glyphicon glyphicon-user"></span>&nbsp;{
  
  {form.name.label}}</label>
            {
  
  {form.name}}
             {% for error in form.name.errors %}
                <div class="col-md-12">
                    <p style="color:red">{
  
  { error }}</p>
                </div>
             {% endfor %}
        </div>
        <div class="col-md-12" id="error_contact"></div>
        <div class="form-group">
            <label for="input_password"><span class="glyphicon glyphicon-lock"></span>&nbsp;{
  
  {form.pwd.label}}</label>
            {
  
  {form.pwd}}
            {% for error in form.pwd.errors %}
                <div class="col-md-12">
                    <p style="color:red">{
  
  { error }}</p>
                </div>
             {% endfor %}
        </div>
        <div class="col-md-12" id="error_password"></div>
        {
  
  {form.submit}}
        {
  
  {form.csrf_token}}
    </fieldset>
</form>a
  • 测试会员登录功能

 

 会员退出

  • 定义退出视图函数
# 会员退出
@home.route('/logout/')
def logout():
    session.pop("user", None)
    session.pop("user_id", None)
    return redirect(url_for("home.login"))
  • 定义登录装饰器
# 登录装饰器
def user_login_required(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
  • 测试会员退出功能以及访问需要登录后才能访问的页面

3.修改会员资料

显示会员信息

  • 定义会员信息表单
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[345789]\\d{9}", 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",
        }
    )
  • 定义视图函数
# 会员详情
@home.route('/user/', methods=['GET', 'POST'])
@user_login_required
def user():
    form = UserdetailForm()
    form.face.validators = []  # 默认图片为空
    user = User.query.get(int(session['user_id']))
    # 设置表单字段初始值
    if request.method == 'GET':
        form.name.data = user.name
        form.email.data = user.email
        form.phone.data = user.phone
        form.face.data = user.face
        form.info.data = user.info
    if form.validate_on_submit():
        data = form.data
    return render_template("home/user.html", form=form, user=user)
  • 填写模板数据
<form novalidate role="form" method="post" enctype="multipart/form-data">
    <fieldset>
            <div class="form-group">
                <label for="input_name"><span class="glyphicon glyphicon-user"></span>&nbsp;{
  
  {form.name.label}}</label>
                {
  
  {form.name}}
                {% for error in form.name.errors %}
                <div class="col-md-12">
                    <p style="color:red">{
  
  { error }}</p>
                </div>
                {% endfor %}
            </div>
            <div class="col-md-12" id="error_name"></div>
            <div class="form-group">
                <label for="input_email"><span class="glyphicon glyphicon-envelope"></span>&nbsp;{
  
  {form.email.label}}</label>
                {
  
  {form.email}}
                 {% for error in form.email.errors %}
                <div class="col-md-12">
                    <p style="color:red">{
  
  { error }}</p>
                </div>
                {% endfor %}
            </div>
            <div class="col-md-12" id="error_email"></div>
            <div class="form-group">
                <label for="input_phone"><span class="glyphicon glyphicon-phone"></span>&nbsp;{
  
  {form.phone.label}}</label>
                {
  
  {form.phone}}
                 {% for error in form.phone.errors %}
                <div class="col-md-12">
                    <p style="color:red">{
  
  { error }}</p>
                </div>
                {% endfor %}
            </div>
            <d
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cdtaogang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值