BBS项目搭建分步过程

BBS项目搭建分步过程

1. 注册页面补充完善

# 注册前端文件 register.html文件中补充:
// 提交ajax
        $.ajax({
            url: '',
            type: 'post',
            data: myFormData,
            contentType: false,
            processData: false,
            success: function (res) {
                console.log(res)
                if (res.status == 200) {
                    layer.msg(res.msg, {icon:1}, function () {
                        location.href = res.url;
                    })
                } else {
                    layer.msg(res.msg,);
                }
            }
        })
    })
</script>
</body>
</html>



# views.py中补充:

from django.http import JsonResponse
from app01 import models

# 1.注册功能
def register(request):
    # 后端一定要对参数进行验证
    if request.method == 'POST':
        # 返回的是json格式的数据
        back_dic = {'status': 200, 'msg': '注册成功', 'data': {}}
        # 1.1. 接收参数
        username = request.POST.get('username')
        password = request.POST.get('password')
        re_password = request.POST.get('re_password')
        email = request.POST.get('email')
        img = request.POST.get('img')

        # 1.2. 验证参数, 先验证不正确的参数
        if not username:
            '''
                响应状态码
                业务状态码
                财务相关的业务,用户相关的,订单相关的
                1001         2001      30
            '''
            back_dic['status'] = 1001
            back_dic['msg'] = '用户名必须填写'
            return JsonResponse(back_dic)

        if password != re_password:
            back_dic['status'] = 1002
            back_dic['msg'] = '两次密码不一致'
            return JsonResponse(back_dic)

        # 验证用户名是否存在
        res = models.UserInfo.objects.filter(username=username).first()
        if res:
            back_dic['status'] = 1003
            back_dic['msg'] = '用户名已经存在'
            return JsonResponse(back_dic)

        # 1.3. 处理正确的业务逻辑
        data_dic = {}
        if img != 'undefined':
            data_dic['avatar'] = img

        # 处理密码
        import hashlib
        from django.conf import settings
        m = hashlib.md5()
        password = password + settings.SECRET_KEY
        m.update(password.encode('utf8'))
        password = m.hexdigest()

        data_dic['username'] = username
        data_dic['password'] = password
        data_dic['email'] = email

        # 1.4. 数据入库
        models.UserInfo.objects.create(**data_dic)  # 传入所有获取的数据

        # 1.5. 返回数据
        back_dic['url'] = '/login/'
        return JsonResponse(back_dic)
    return render(request, 'register.html')

image

image

2. 登录页面搭建

# views.py中写入登录以及验证码功能:
# 2. 登录
def login(request):
    return render(request, 'login.html')


# 3. 生成验证码
"""
图片相关的模块
    pip3 install pillow
"""
from PIL import Image, ImageDraw, ImageFont

"""
Image:生成图片
ImageDraw:能够在图片上乱涂乱画
ImageFont:控制字体样式
"""
from io import BytesIO, StringIO

"""
内存管理器模块
BytesIO:临时帮你存储数据 返回的时候数据是二进制
StringIO:临时帮你存储数据 返回的时候数据是字符串
"""
import random

def get_random():
    # (100, 100, 100)
    return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)

def get_code(request):
    # 写图片验证码
    img_obj = Image.new('RGB', (430, 35), get_random())
    img_draw = ImageDraw.Draw(img_obj)  # 产生一个画笔对象
    img_font = ImageFont.truetype('static/font/font.ttf', 30)  # 字体样式 大小 字体文件可自行百度下载

    # 随机验证码  五位数的随机验证码  数字 小写字母 大写字母
    code = ''
    for i in range(4):
        random_upper = chr(random.randint(65, 90))
        random_lower = chr(random.randint(97, 122))
        random_int = str(random.randint(0, 9))
        # 从上面三个里面随机选择一个
        tmp = random.choice([random_lower, random_upper, random_int])
        # 将产生的随机字符串写入到图片上
        """
        为什么一个个写而不是生成好了之后再写
        因为一个个写能够控制每个字体的间隙 而生成好之后再写的话
        间隙就没法控制了
        """
        img_draw.text((i * 60 + 60, -2), tmp, get_random(), img_font)
        # 拼接随机字符串
        code += tmp
    print(code)
    # 随机验证码在登陆的视图函数里面需要用到 要比对 所以要找地方存起来并且其他视图函数也能拿到
    request.session['code'] = code
    # request.session['code'] = code
    io_obj = BytesIO()
    img_obj.save(io_obj, 'png')
    return HttpResponse(io_obj.getvalue())




# 新建login.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <h1 class="text-center">登录页面</h1>
        <div class="col-md-8 col-md-offset-2">
            <form action="">
                <div class="form-group">
                    <label for="username">用户名</label>
                    <input type="text" id="username" class="form-control">
                </div>
                <div class="form-group">
                    <label for="username">密码</label>
                    <input type="password" id="password" class="form-control">
                </div>

                <div class="form-group">
                    <label for="myfile">
                        验证码
                    </label>
                    <div class="row">
                        <div class="col-md-6">
                            <input type="text" class="form-control" id="get_code">
                        </div>
                        <div class="col-md-6">
                            <img src="/get_code/" id="re_code" alt="" style="width: 445px; height: 35px;">
                        </div>
                    </div>
                </div>
                <input type="button" class="btn btn-success btn-block" value="登录">
            </form>
        </div>

    </div>
</div>
</body>
</html>


# 路由不要忘了:
    # 登录页面
    url(r'^login/', views.login),

    # 生成验证码
    url(r'^get_code/', views.get_code),

image

3. 登录后端逻辑的实现

import hashlib
from django.conf import settings

# 封装密码处理功能
def get_pwd(password):
    m = hashlib.md5()
    password = password + settings.SECRET_KEY
    m.update(password.encode('utf-8'))
    return m.hexdigest()


# 补充登录具体功能:
# 2. 登录
def login(request):
    if request.method == 'POST':
        # 定义返回数据的格式
        back_dic = {'status': 200, 'msg': '登录成功', }

        # 接收参数
        username = request.POST.get('username')
        password = request.POST.get('password')
        code = request.POST.get('code')

        # 验证参数
        if code.upper() != request.session.get('code').upper():  # .upper() 转大写 不区分大小写了
            back_dic['status'] = 1004
            back_dic['msg'] = '验证码不正确'
            return JsonResponse(back_dic)

        if not username:
            back_dic['status'] = 1005
            back_dic['msg'] = '用户名必须填写'
            return JsonResponse(back_dic)

        # 登录逻辑
        password = get_pwd(password)  # 获取加密之后的密码

        # res = models.UserInfo.objects.filter(username=username, password=password).first()
        '''防止撞库 同时查询用户名和密码 不要只匹配一项就返回结果给用户'''
        res = models.UserInfo.objects.filter(username=username, password=password).first()
        if not res:
            back_dic['status'] = 1006
            back_dic['msg'] = '用户名或者密码不正确'
            return JsonResponse(back_dic)

        # 记录用户信息的
        request.session['username'] = username
        request.session['id'] = res.id

        back_dic['url'] = '/home/'
        return JsonResponse(back_dic)

    return render(request, 'login.html')


# 在login.html中 添加数据提交:
"""
引入标签不要忘了:
<script src="/static/layer-v3.5.1/layer/layer.js"></script>
"""

"""body标签内添加script标签绑定事件:"""
<script>
    // 更换验证码
    $("#re_code").click(function () {
        {#var old_code = $('#re_code').attr('src');#}
        var old_code = $(this).attr('src');
        {#$('#re_code').attr('src', old_code);#}
        $(this).attr('src', old_code);

    })


    $('.btn').click(function () {
        var username = $('#username').val();
        var password = $('#password').val();
        var code = $('#get_code').val();
        // 验证参数
        if (!username) {
            layer.msg('用户名必须填写');
            return
        }

        if (!password) {
            layer.msg('密码必须填写');
            return;
        }
        if (!code) {
            layer.msg('验证码必须填写');
            return;
        }
        var data = {'username': username, 'password': password, 'code': code}

        // 提交ajax 请求
        $.ajax({
            url: '',
            type: 'post',
            data: data,  // 参数过多时 单独定义变量存储
            success: function (res) {
                console.log(res); // 查看后端返回的数据,
                if (res.status == 200) {
                    layer.msg(res.msg, {}, function () {
                        location.href = res.url;
                    })
                } else {
                    layer.msg(res.msg)
                }
            }

        })

    })
</script>

image

4. 首页创建

# 路由:
    # 首页
    url(r'^home/', views.home),
    
# views.py补充首页功能:
# 4. 首页
def home(request):
    return render(request, 'home.html', locals())
    
    
# 新建home.html文件 使用bootstrap的导航条样式:  
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>

<nav class="navbar navbar-inverse">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">py20BBS</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">

            <ul class="nav navbar-nav">
                <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                <li><a href="#">Link</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false">Dropdown <span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="#">Action</a></li>
                        <li><a href="#">Another action</a></li>
                        <li><a href="#">Something else here</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">Separated link</a></li>
                        <li role="separator" class="divider"></li>
                        <li><a href="#">One more separated link</a></li>
                    </ul>
                </li>


            </ul>
            <form class="navbar-form navbar-left">
                <div class="form-group">
                    <input type="text" class="form-control" placeholder="Search">
                </div>
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
            <ul class="nav navbar-nav navbar-right">
                {% if request.session.username %}
                    <li><a href="#">{{ request.session.username }}</a></li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                           aria-expanded="false">更多操作 <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#" data-toggle="modal" data-target=".bs-example-modal-lg">修改密码</a></li>
                            <li><a href="#">后台管理</a></li>
                            <li><a href="/logout/">退出系统</a></li>
                        </ul>
                    </li>
                {% else %}
                    <li><a href="/register/">注册</a></li>
                    <li><a href="/login/">登录</a></li>
                {% endif %}

            </ul>
        </div><!-- /.navbar-collapse -->
        <div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
            <div class="modal-dialog modal-lg" role="document">
                <div class="modal-content">
                    <div class="row">
                        <h1 class="text-center">修改密码</h1>
                        <div class="col-md-8 col-md-offset-2">
                            <div class="form-group">
                                <label for="old_pwd">
                                    原密码:
                                </label>
                                <input type="text" id="old_pwd" class="form-control">
                            </div>
                            <div class="form-group">
                                <label for="new_pwd">
                                     新密码:
                                </label>
                               <input type="text" id="new_pwd" class="form-control">
                            </div>
                            <div class="form-group">
                                <label for="re_pwd">确认密码:</label>
                                <input type="text" id="re_pwd" class="form-control">
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                                <button type="button" class="btn btn-primary set_pwd">提交</button>
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>
    </div><!-- /.container-fluid -->
</nav>

</body>
</html>

image

image

5. 退出系统及修改密码功能的实现

# html文件内容在第4点 home.html文件中

# 添加路由:
    # 退出系统
    url(r'^logout/', views.logout),

    # 修改密码
    url(r'^set_pwd/', views.set_pwd),

    
# views.py补充功能:
# 5. 退出系统
def logout(request):
    request.session.flush()
    return redirect('/login/')


# 6. 修改密码
def set_pwd(request):
    if request.method == 'POST':
        # 返回的是json格式的数据
        back_dic = {'status': 200, 'msg': '修改成功', 'data': {}}
        # 1. 接收参数
        old_pwd = request.POST.get('old_pwd')
        new_pwd = request.POST.get('new_pwd')
        re_pwd = request.POST.get('re_pwd')

        # 验证参数
        if not old_pwd:
            back_dic['status'] = 1008
            back_dic['msg'] = '原密码必须填写'
            return JsonResponse(back_dic)
        if re_pwd != new_pwd:
            back_dic['status'] = 1009
            back_dic['msg'] = '两次密码不一致'
            return JsonResponse(back_dic)

        # 修改密码
        password = get_pwd(new_pwd) # 获取加密之后的密码
        models.UserInfo.objects.filter(pk=request.session.get('id')).update(password=password)

        return JsonResponse(back_dic)



# html文件内容写在第4点home.html文件中:
<script>
    $('.set_pwd').click(function () {
        var old_pwd = $('#old_pwd').val();
        var new_pwd = $('#new_pwd').val();
        var re_pwd = $('#re_pwd').val();
        // 验证参数
        if (!old_pwd) {
            layer.msg('原密码必须填写');
            return
        }

        if (!new_pwd) {
            layer.msg('新密码必须填写');
            return;
        }
        if (!re_pwd) {
            layer.msg('确认必须填写');
            return;
        }
        var data = {'old_pwd': old_pwd, 'new_pwd': new_pwd, 're_pwd': re_pwd}
        // 提交ajax 请求
        $.ajax({
            url: '/set_pwd/',
            type: 'post',
            data: data,
            success: function (res) {
                console.log(res); // 查看后端返回的数据,
                if (res.status == 200) {
                    layer.msg(res.msg, {}, function () {
                        location.reload();
                    })
                } else {
                    layer.msg(res.msg)
                }
            }

        })
    })
</script>

image

posted @ 2022-03-14 21:32  Deity_JGX  阅读(184)  评论(0编辑  收藏  举报