DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • BBS

    • 登陆注册
      • BBS数据表分析
      • BBS表的创建
      • 注册页面的搭建
      • 注册功能的实现
      • 登陆页面的搭建
      • 登陆功能的实现
    • 个人站点
    • 博客
    • 评论
  • 订单平台

  • CRM

  • flask+layui

  • django+layui

  • 供应链

  • 实战
  • BBS
DC
2023-12-01
目录

登陆注册

BBS页面的搭建使用的是bootstrap! 在真实的办公中,是不会使用这个技术的,jquery都使用的很少..
所以不必纠结于前端的实现,了解即可.. 需要熟练掌握的是后端代码的书写!!

# BBS数据表分析

记住一点! 做任何项目,先设计表!! 设计出合理的表意味着项目完成了一半(´▽`).
博客园的功能实现很简单,但一旦用户量很大,那就不简单啦,一个首页就够我们玩的啦,现在还体验不到.(つД`)ノ

1.用户表 - 扩展auth_user表
    -- phone  (手机号可以为空)
    -- avatar  
    -- create_time
    ---- 用户表:站点表 = 1:1
2.站点表
    https://www.cnblogs.com/linhaifeng
    https://www.cnblogs.com/liuqingzheng
    输入一个网址,打开一个博客,这叫做站点表!!linhaifeng、liuqingzheng这叫作站点名称!每个站点的CSS不一样.
    -- 站点名称  
    -- 站点标题
    -- 站点样式(存储css路径)
3.标签表
    注意: 分类与标签不一样!eg:一个班级的同学可以按照男女、好看程度等进行分类;对某一个人的描述,相当于给此人打上了标签.
    -- 标签名
    ---- 站点表:标签表 = 1:n
4.分类表
    公司里可能有现成的分类树算法: 逐级分类.
    -- 分类名
    ---- 站点表:分类表 = 1:n
5.文章表(BBS项目中最核心的一张表)
    文章最末尾显示的有点赞数、点踩数、评论数
    如何实现呢?初次展示文章页面和用户点击点赞点踩时,去点赞点踩表里查?使用缓存?
    但要明确一点,每次查库不大好,会拖慢该页面的打开时间!!
    So,当每次有人点赞点踩时,不仅写入点赞点踩表,文章表的点赞数也要加1,这是一个优化策略!!
    -- 文章标题
    -- 摘要
    -- 内容
    -- 发布时间
    -- 点赞数
    -- 点踩数
    -- 评论数
    ---- 站点表:文章表 = 1:n
    ---- 分类表:文章表 = 1:n
    ---- 标签表:文章表 = n:n  (半自动)
6.点赞点踩表
    谁给哪篇文章点赞了还是点踩了(相当于用户表:文章表=n:n,纯手动的创建了第三张表)
    ---- user    外键
    ---- article 外键
    -- updown(bool值)
7.评论表
    谁给哪篇文章什么时间评论了什么内容
    注意:一级评论,二级评论,三级评论.. !!无限级分类!!(自己与自己关联)
    ---- user    外键
    ---- article 外键
    -- content
    -- create_time
    ---- pid (自关联 值为评论表的id值,意味着该评论是哪条评论的子评论.不一定有子评论,所以该字段允许为空!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

# BBS表的创建

建表先建基础字段!!

创建数据库,将DATABASES配置成mysql;
书写扩展表的配置项AUTH_USER_MODEL;
配置静态文件路径STATICFILES_DIRS;
默认用的是mysqldb,将其改成pymysql..
进行数据库迁移的两条命令!
表一旦建立成功,大吉大利,今晚吃鸡Hhh.

Ps: 将某些外键允许为空,是便于测试.. 可以迁移更改,也可以直接在navicat中设计表字段更改.

from django.db import models
from django.contrib.auth.models import AbstractUser


class UserInfo(AbstractUser):
    phone = models.CharField(max_length=32, null=True, blank=True, verbose_name='手机号')
    # -- 只要给avatar字段传递文件对象,图片就会上传到指定文件夹!
    #    参数upload_to写存储图片的路径!
    #    参数default表明不上传头像的话使用默认图片!
    avatar = models.FileField(upload_to='static/img/', default='static/img/default.png', verbose_name='头像')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间')  # -- 自动写入当前时间!
    site = models.OneToOneField(to='Site', null=True)


class Site(models.Model):
    site_name = models.CharField(max_length=64, verbose_name='站点名称')
    site_title = models.CharField(max_length=64, verbose_name='站点标题')
    site_css = models.CharField(max_length=128, verbose_name='站点样式路径')

    def __str__(self):
        return self.site_name


class Tag(models.Model):
    name = models.CharField(max_length=64, verbose_name='标签名')
    site = models.ForeignKey(to='Site')

    def __str__(self):
        return self.name


class Category(models.Model):
    name = models.CharField(max_length=64, verbose_name='分类名')
    site = models.ForeignKey(to='Site')

    def __str__(self):
        return self.name


class Article(models.Model):
    title = models.CharField(max_length=256, verbose_name='文章标题')
    desc = models.CharField(max_length=256, verbose_name='简介')
    content = models.TextField(verbose_name='文章内容')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间')
    # -- 这三个字段是优化字段!
    up_num = models.IntegerField(verbose_name='点赞数', null=True, blank=True)
    down_num = models.IntegerField(verbose_name='点踩数', null=True, blank=True)
    comment_num = models.IntegerField(verbose_name='评论数', null=True, blank=True)
    # -- 外键关系
    site = models.ForeignKey(to='Site', null=True)
    category = models.ForeignKey(to='Category', null=True)
    tag = models.ManyToManyField(to='Tag',
                                 through='Article2Tag',
                                 through_fields=('article', 'tag'))

    def __str__(self):
        return self.title


class Article2Tag(models.Model):
    article = models.ForeignKey(to="Article", null=True)
    tag = models.ForeignKey(to="Tag", null=True)


class UpdandDown(models.Model):
    user = models.ForeignKey(to="UserInfo")
    article = models.ForeignKey(to="Article")
    is_up = models.BooleanField()  # -- 存True/False,但表中的表现是1/0


class Comment(models.Model):
    user = models.ForeignKey(to="UserInfo")
    article = models.ForeignKey(to="Article")
    content = models.CharField(max_length=256, verbose_name='评论内容')
    create_time = models.DateTimeField(auto_now_add=True, verbose_name='评论时间')
    # -- 自关联
    #    这里可以 to='Comment'
    parent = models.ForeignKey(to='self', null=True, verbose_name='父id')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

# 注册页面的搭建

借助文件阅读器实现在页面上实时展示上传的头像图片!!

三把斧再现(⁎⁍̴̛ᴗ⁍̴̛⁎)

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^register/', views.register),
]
1
2
3
4
5
6
7
8

views.py

from django.shortcuts import render

def register(request):
    return render(request, 'register.html')
1
2
3
4

register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <title>Title</title>
</head>
<body>
{# div.container-fluid > div.row > div#}
<div class="container-fluid">
    <div class="row">
        <h1 class="text-center">注册页面</h1>
        <div class="col-md-4 col-md-offset-4">
            <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="password">密码:</label>
                    <input type="password" id="password" class="form-control">
                </div>
                <div class="form-group">
                    <label for="re_password">确认密码:</label>
                    <input type="password" id="re_password" class="form-control">
                </div>
                <div class="form-group">
                    <label for="my_file">
                        上传头像:
                        <img src="/static/img/default.png" width="80" alt="" id="my_img">
                    </label>
                    {# display:none !!#}
                    <input type="file" id="my_file" style="display: none">
                </div>
                <input type="button" class="btn btn-success pull-right" value="注册">
            </form>
        </div>
    </div>
</div>
<script>
    $('#my_file').change(function () {
        // 借助于JS的文件阅读器(了解)
        // step1:拿到文件阅读器对象
        let myFileReader = new FileReader()
        // step2:拿到文件对象
        let myFileObj = $('#my_file')[0].files[0]  // 死死的记住
        // step3:把文件对象给文件阅读器来读取数据
        //   该操作是异步的!使用onload加载完毕后再执行其它操作.
        myFileReader.readAsDataURL(myFileObj)
        myFileReader.onload = function () {
            console.log(myFileReader.result)
            // 将读出的图片数据作为img的src属性的值,该值并不是路径,因为该图片并没有上传到后端!
            // 当然可以ajax上传图片,然后将src改为后端的路径,不推荐这样做!!
            $('#my_img').attr('src', myFileReader.result)
        }
    })
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# 注册功能的实现

用户名是否存在只能在后端进行校验!!

register.html
使用了layer组件!!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    {% load static %}
    <script src="{% static 'layer-v3.5.1/layer/layer.js' %}"></script>
    <title>Title</title>
</head>
<body>
{# div.container-fluid > div.row > div#}
<div class="container-fluid" ...>
<script>
    // ★ 实现上传的头像图片在页面的实时展示
    $('#my_file').change(function () {...})

    // ★ 实现注册功能
    $('.btn').click(function () {
        // step1:实例化FormData
        let myFormDataObj = new FormData();
        // step2:获取表单数据
        let username = $('#username').val();
        let password = $('#password').val();
        let re_password = $('#re_password').val();
        // 在前端进行表单数据的验证!(前端的验证弱不禁风,Hhh)
        if (!username) {
            layer.msg('用户名必须填写!')
            return
        }
        if (!password) {
            layer.msg('密码必须填写!')
            return
        }
        if (!re_password) {
            layer.msg('确认密码必须填写!')
            return
        }
        if (password !== re_password) {
            layer.msg('两次密码必须一致!')
            return
        }
        // step3:添加普通数据
        myFormDataObj.append('username', username)
        myFormDataObj.append('password', password)
        myFormDataObj.append('re_password', re_password)
        // csrf验证
        myFormDataObj.append('csrfmiddlewaretoken', '{{ csrf_token }}')
        // step4:添加文件对象
        myFormDataObj.append('avatar', $('#my_file')[0].files[0])
        // step5:发送ajax请求
        $.ajax({
            url: '',
            type: 'post',
            data: myFormDataObj,
            contentType: false,
            processData: false,
            success: function (res) {
                {# 没有达到预定的效果,如何调试? 打印后端返回的结果 res、typeof res、res.url#}
                if (res.code == 200) {
                    layer.msg(res.msg, {icon: 1}, function () {
                        // 注册成功跳转指定页面
                        location.href = res.url
                    })
                } else {
                    layer.msg(res.msg, {icon: 2})
                }
            }
        })
    })
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

views.py

from django.shortcuts import render
from django.http import JsonResponse
from app01 import models
import hashlib


def register(request):
    # ★ 粗略的分,分为4步:接收操作、验证参数、写逻辑、返回数据格式
    if request.method == "POST":
        back_dic = {
            'code': 200,  # -- 200响应状态码
            'msg': '注册成功!'
        }
        username = request.POST.get('username')
        password = request.POST.get('password')
        re_password = request.POST.get('re_password')
        avatar = request.FILES.get('avatar')  # -- avatar是一个文件对象,若前端不传,结果为None
        # -- 在后端进行表单参数的验证
        if not username:
            back_dic['code'] = 1001  # -- 1001业务状态码
            back_dic['msg'] = '用户名不能为空!'
            return JsonResponse(back_dic)
        if not password:
            back_dic['code'] = 1002
            back_dic['msg'] = '密码不能为空!'
            return JsonResponse(back_dic)
        if not re_password:
            back_dic['code'] = 1003
            back_dic['msg'] = '确认密码不能为空!'
            return JsonResponse(back_dic)
        if password != re_password:
            back_dic['code'] = 1004
            back_dic['msg'] = '两次密码必须一致!'
            return JsonResponse(back_dic)
        # -- 验证用户名是否注册
        res = models.UserInfo.objects.filter(username=username).first()
        if res:
            back_dic['code'] = 1005
            back_dic['msg'] = '用户名已经存在!'
            return JsonResponse(back_dic)
        # -- 入库
        # -- 密码用md5算法加密,为了提高安全性可以加盐!!secret的值写到setting配置文件中
        #    password += settings.secret
        #    每个用户注册的盐都是一样的,还可以玩的更花,每个用户的 盐/一随机字符串 都不一样!
        m = hashlib.md5()
        m.update(password.encode('utf-8'))
        password = m.hexdigest()
        dic = {
            'username': username,
            'password': password,
        }
        if avatar:
            dic['avatar'] = avatar  # -- 不上传返回的是None,若上传,覆盖默认的路径值
        # models.UserInfo.objects.create_user(**dic)  # -- Auth模块的加密
        models.UserInfo.objects.create(**dic)  # -- 自个儿用hash算法对密码进行加密
        back_dic['url'] = '/login/'  # -- 注册成功后跳转登陆页面!
        return JsonResponse(back_dic)

    return render(request, 'register.html')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# 登陆页面的搭建

登陆页面里图片验证码的实现了解即可,不必纠结.. 真实的工作中不会用它!

三把斧再现(⁎⁍̴̛ᴗ⁍̴̛⁎)

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^register/', views.register),
    url(r'^login/', views.login),
    url(r'^get_code/', views.get_code),  # -- 获取验证码
]
1
2
3
4
5
6
7
8
9
10

views.py
特别注意, 导入字体文件的工作目录是Django的启动文件manage.py所在的目录,而不是views.py所在的目录!!!

from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from app01 import models
import hashlib

import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO, StringIO


def register(request):...


def login(request):
    return render(request, 'login.html')


def get_random():
    # -- 返回RGB的颜色!
    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)  # -- 产生一个画笔对象
    # -- 下载免费字体的网址:http://www.zhaozi.cn/s/freefont/
    img_font = ImageFont.truetype('static/font/hello.ttf', 30)  # -- 字体样式 大小
    # -- 五位数的随机验证码
    code = ''
    for i in range(5):
        random_upper = chr(random.randint(65, 90))  # -- A-Z
        random_lower = chr(random.randint(97, 122))  # -- a-z
        random_int = str(random.randint(0, 9))  # -- 0-9
        # -- random.choice从上面三个里面任意选择一个
        tmp = random.choice([random_lower, random_upper, random_int])
        # -- 将产生的随机字符串写入到图片上
        #    Q1:为什么一个个写而不是生成好了之后再写?
        #    A1:因为一个个写能够控制每个字体的间隙,而生成好之后再写的话,间隙就没法控制了!
        #    Q2:为什么要把验证码写到图片上呢?在页面上直接展示不行吗?
        #    A2:为了安全,可以提高防范机器人的概率!
        img_draw.text((i * 60 + 60, -2), tmp, get_random(), img_font)
        # -- 拼接随机字符串
        code += tmp
    print('验证码:', code)
    # -- 随机验证码在登陆的视图函数里面需要用到,要比对,所以要找地方存起来并且其他视图函数也能拿到
    #    cookie/session是一个选择,redis缓存数据库也行,但存到mysql中不推荐.
    request.session['code'] = code
    io_obj = BytesIO()
    img_obj.save(io_obj, 'png')
    return HttpResponse(io_obj.getvalue())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    {% load static %}
    <script src="{% static 'layer-v3.5.1/layer/layer.js' %}"></script>
    <title>Title</title>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <h1 class="text-center">登陆页面</h1>
        <div class="col-md-4 col-md-offset-4">
            <div class="form-group">
                <label for="username">用户名:</label>
                <input type="text" id="username" class="form-control">
            </div>
            <div class="form-group">
                <label for="password">密码:</label>
                <input type="password" id="password" class="form-control">
            </div>
            <div class="form-group">
                <label for="code">验证码:</label>
                <div class="row">
                    <div class="col-md-6">
                        <input type="text" id="code" class="form-control">
                    </div>
                    <div class="col-md-6">
                        {# /get_code/会请求后端这个接口! #}
                        <img src="/get_code/" alt="" width="208" height="33">
                    </div>
                </div>
            </div>
            <input type="button" class="btn btn-success pull-right" value="登陆">
        </div>
    </div>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 登陆功能的实现

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    {% load static %}
    <script src="{% static 'layer-v3.5.1/layer/layer.js' %}"></script>
    <title>Title</title>
</head>
<body>
<div class="container-fluid" ...>
<script>
    $('.btn').click(function () {
        let username = $("#username").val()
        let password = $("#password").val()
        let code = $("#code").val()
        if (!username) {
            layer.msg('用户名必须填写!')
            return
        }
        if (!password) {
            layer.msg('密码必须填写!')
            return
        }
        if (!code) {
            layer.msg('验证码必须填写!')
            return
        }
        // 发动Ajax请求
        $.ajax({
            url: '',
            type: 'post',
            data: {
                'username': username,
                'password': password,
                'code': code,
                'csrfmiddlewaretoken': '{{ csrf_token }}',
            },
            success: function (res) {
                if (res.code == 200) {
                    layer.msg(res.msg, {icon: 1}, function () {
                        location.href = res.url
                    })
                } else {
                    layer.msg(res.msg, {icon: 2})
                }
            }
        })
    })
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

views.py

from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from app01 import models
import hashlib

import random
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO, StringIO


def register(request):...


def get_random():...


def get_code(request):...


def login(request):
    # -- 判断请求方式,接收参数,验证参数,处理数据
    if request.method == "POST":
        back_dic = {
            'code': 200,
            'msg': '登陆成功'
        }
        username = request.POST.get('username')
        password = request.POST.get('password')
        code = request.POST.get('code')
        if not username:
            back_dic['code'] = 1001
            back_dic['msg'] = '用户名不能为空!'
            return JsonResponse(back_dic)
        if not password:
            back_dic['code'] = 1002
            back_dic['msg'] = '密码不能为空!'
            return JsonResponse(back_dic)
        # -- 验证码是否正确?
        if request.session.get('code') != code:
            back_dic['code'] = 1006s
            back_dic['msg'] = '验证码错误!'
            return JsonResponse(back_dic)
        # -- 用户名和密码是否匹配
        m = hashlib.md5()
        m.update(password.encode('utf-8'))
        password = m.hexdigest()
        # Ps:这里最好用户名和密码一起查,不用确切的告知是用户名不存在还是密码错误,降低撞库的风险.
        res = models.UserInfo.objects.filter(username=username, password=password).first()
        if not res:
            back_dic['code'] = 1007
            back_dic['msg'] = '用户名或密码不正确!'
        # -- 用session保存用户信息
        #    当业务逻辑复杂的时候,会保存用户多个或所有的信息作为session
        #    request.session['info'] = res -- 这样就可取出session/用户对象,使用.点语法!
        request.session['username'] = username
        request.session['id'] = res.id  # -- 其它地方就可以通过session取登陆用户id啦!!
        back_dic['url'] = '/home/'
        return JsonResponse(back_dic)
    return render(request, 'login.html')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

个人站点

个人站点→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式