注册案例

1. 打开终端, 进入工程目录, 创建子目录

django-admin startapp 子应用名

 

 

2. 编辑工程目录下的settings.py文件, 在INSTALLED_APPS中注册子应用

 

 

3. 编辑子项目的项目视图view.py, 定义一个register项目视图函数

 

 

4. 在子应用中新添urls.py文件, 添加URL配置

 

from django.urls import re_path
from users import views

urlpatterns = [
    re_path(r'^register/$', views.register),
]

 

 

 

5. 在工程项目的文件夹中, 包含子应用下方的urls.py文件

urlpatterns = [
    ...
    path('', include('users.urls')),
]

 

 

 6. 使用模板存放html模板文件

  1. 在工程项目目录中创建一个templates目录, 用来存放创建的模板文件

  

 

   2. 编辑工程项目目录中的settings.py文件, 在TEMPLATES配置项中设置templates为模板文件存放目录

 

# __file__:指定当前文件
# os.path.abspath(__file__):获取当前文件的绝对路径
# os.path.dirname(传入路径):获取传入路径的上级目录
# 注意:此处指的是获取 settings.py 文件所在目录的上级目录,即外层的 web_demo 目录
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

   3. 在templates目录下创建一个模板文件index.html

 

   4. 编辑子应用下的view.py文件, 修改其中register view.py代码

# /register/
def register(request):
    """注册View视图函数"""
    # 使用 register.html 模板文件,返回响应
    return render(request, 'register.html')

注意:render 是使用html模板文件的函数,其作用就是加载对应模板文件的内容,并进行页面的渲染,给客户端返回HttpResponse响应

render("请求对象", "html模板文件名", context="给html模板文件传递的数据", ...)

 

   5. 运行django项目, 通过浏览器访问网址可以看到注册页面

 7. 请求数据

  1. 关闭CSRF保护

    1. 当我们输入用户名和密码时, 会出现403报错, 这错误就是CSRF验证失败, 

    2. 为避免以上错误, 我们需将需要编辑 web_demo/settings.py 文件,修改配置文件中的 MIDDLEWARE 配置项,将CSRF保护机制关闭。

 

 

   2. 请求方式的获取

    1. 针对于用户注册的案例,我们希望在 register View视图函数中处理两种不同的业务逻辑:

GET /register/: 获取注册页面
POST /register/: 进行注册信息的保存

    1) 编辑子项目的views.py文件, 修改views视图函数

 

     2) 通过浏览器栏访问地址 ---- GET请求方式, 返回注册页面

 

 

    3) 在注册表中测试, 输入注册信息, 返回注册按钮 ---- POST请求, 返回注册信息

 

 3. POST表单提交数据获取

可以通过request.POST来获取对应的数据, 接下来就在子项目的view视图函数的POST逻辑中, 进行注册参数的获取

  1. 编辑子项目中的view.py文件, 修改view.py的视图函数

 

   2. 通过注册页面进行注册表提交, 可以在服务端看到打印和获取的用户名和密码数据

 

 

 

 

 8. 创建模型对应的用户数据表

1. 基础知识介绍 ---- 模型定义的基本格式

  模型定义在子项目中的modle.py文件夹下, 具体格式:

from django.db import models

class 模型类名(models.Model):
    模型字段名 = models.字段类型(选项参数)
    模型字段名 = models.字段类型(选项参数)
    模型字段名 = models.字段类型(选项参数)

    class Meta:
        db_table = '数据表名'

 2. 基础知识介绍 ---- 模型对用数据表的创建

  在定义完对应的模型类后, 如果要生成对应的数据表, 需要进行对应的模型迁移操作, 具体操作分为两步

# 根据模型类生成数据迁移文件
python manage.py makemigrations
# 根据迁移文件生成数据库中的数据表
python manage.py migrate

3. 用户模型类的定义

编辑modle.py文件, 在其中定义一个User用户模型类

 1 from django.db import models
 2 
 3 
 4 class User(models.Model):
 5     """用户模型类"""
 6     # verbose_name:对字段的解析说明,相当于注释的作用
 7     # max_length:指定字符串内容的最大长度为多少个字符
 8     username = models.CharField(max_length=20, verbose_name='用户名')
 9     password = models.CharField(max_length=128, verbose_name='密码')
10     # default:设置向数据库添加数据时,字段使用的默认值
11     gender = models.BooleanField(default=False, verbose_name='性别')
12     age = models.IntegerField(default=18, verbose_name='年龄')
13     # null=True:生成数据表时,数据表的对应字段允许为NULL
14     mobile = models.CharField(max_length=11, null=True, verbose_name='手机号')
15 
16     class Meta:
17         # 指定迁移时生成的数据表的名称
18         db_table = 'tb_users'
19         # 模型类的解析说明,相当于注释的作用
20         verbose_name = '用户表'

 4. 数据库的配置

  Django框架默认使用sqlite3数据库,sqlite3是一个小型的关系型数据库,主要在移动端使用,企业中大多开发时都会使用mysql关系数据库,我们此处配置Django项目使用mysql数据库。

  1. 链接进入自己的mysql数据库, 创建一个新数据库

# 注意:创建数据库的命令需要在 mysql 终端执行
create database People charset=utf8;

   2. 编辑工程项目中的setting.py文件, 修改其中的DATABASE配置项, 进行数据库的配置

 

   3. 打开终端, 在虚拟环境中安装mysqlclient扩展包, Django的ORM框架需要使用这个扩展包去链接mysql数据库

pip install mysqlclient==2.0.1

 

   4. 链接迁移和表的生成

    1. 执行模型迁移命令, 在数据库中生成数据表

# 生成模型迁移文件
python manage.py makemigrations

 

# 迁移生成数据库中的表
python manage.py migrate

     2. 查看生成的表

 

 

 5. 注册用户数据的保存

通过模型可以直接向数据库中添加数据

# 方式1:创建模型类对象,`对象.save()` 实现数据添加,如:
# 带有 default默认值 或 允许为NULL 的字段数据可以不传
user = User(username='smart', password='123456abc', ...)
user.save()

# 方式2:调用 `模型类.objects.create(...)` 实现数据添加
# create方法实际是对方式①的封装
User.objects.create(username='smart', password='123456abc', ...)

  1. 编辑子应用下的views.py文件, 修改子应用的views视图, 添加数据库保存注册用户的信息逻辑

 

 

   2. 启动Django, 进行注册页面的注册测试, 查看数据库中的数据表

 

 

 

9. Jason响应数据返回

1. 编辑子项目下的views.py文件, 修改如下代码

 

 2. 通过注册页面再次测试, 收到的响应提示如下

 

 10. 页面重定向

  在我们使用其他网站进行注册时,经常会发现注册之后,浏览器直接跳转到了对应网站的登录页面,这些网站的注册响应中,其实并没有返回html页面,也可能没有返回json数据,而且返回了页面重定向,让你的浏览器重新访问网站的登录页面。

  所谓页面重定向, 就是当你去访问网站的门票普格URL网址, 这个网站在响应时会让你访问另外一个网址, 这就叫页面重定向

 

  Django框架中,View视图在返回响应时,如果要返回重定向响应,可以直接调用redirect方法,具体用法如下:

from django.shortcuts import redirect
# 调用 redirect 方法进行响应时的重定向操作
redirect('重定向的URL地址')

1. 登录页面的添加

   1. 在templates目录下添加一个登录的html界面

 

 

   2. 编辑子项目下的views.py文件, 在其添加login views视图函数

 

 

   3. 编辑urls.py文件, 在其中添加url配置选项

 

 

 2. 注册成功重定向

  1. 编辑子目录下的views.py文件, 修改register的部分响应文件

 

 

   2. 再次通过注册测试, 查看客户端响应提示

 11. 功能实现

1. 登录基本功能实现

   根据请求方式的不同实现不同的业务逻辑

  1. 修改子项目中的视图文件, 修改其中的login代码, 增加用户的逻辑判断

  1) 登录成功

 

 

   2) 登录失败

 

 

 12. 状态保存

1. Cookie机制

  使用cookie机制来完善这个案例

  1. 修改templates下的login.html页面, 添加一个可以记住用户名的复选框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面模板</title>
</head>
<body>
    <form method="post" action="/login/">
        username:<input type="text" name="username"><br/>
        password:<input type="password" name="password"><br/>
        <input type="checkbox" name="remember" value="true">记住用户名
        <input type="submit" value="登录">
    </form>
</body>
</html>

   2. 编辑子项目下的views.py文件, 修改login view视图代码, 添加判断是否登录需要记住用户名的逻辑

def login(request):
    """登录View视图函数"""
    if request.method == 'GET':
        ...
    else:
        # 登录业务逻辑
        # 获取 username 和 password
        username = request.POST.get('username')
        password = request.POST.get('password')
        remember = request.POST.get('remember')

        # 进行用户名和密码校验
        try:
            ...
        except User.DoesNotExist:
            ...
        else:
            # 用户名和密码正确
            response = JsonResponse({'message': 'login success'})

            # 判断是否需要记住登录用户名
            if remember == 'true':
                # 记住登录用户名,设置 Cookie 数据,有效期为 14 天
                response.set_cookie('username', username, max_age=14 * 24 * 3600)

            return response

 

 

   3. 接下来我们需要继续修改views.py视图代码, 在返回登录界面时将username填充到表单用户名输入框中

def login(request):
    """登录View视图函数"""
    if request.method == 'GET':
        # 获取客户端传递的 Cookie 数据 username
        username = request.COOKIES.get('username', '')

        # 返回登录页面
        return render(request, 'login.html', context={'username': username})
    else

 

 

   4. 修改模板文件,将 username 填充到登录表单用名输入框中

 

 

   5. 最后再访问登录页面,可以看到记住的用户名就会填充到用户名输入框中:

 

 

   

2. session机制

  1. 基础介绍 ---- session机制的存储方式

    Django 框架默认支持 Session 的存储,具体在 setting.py配置文件中进行了设置:

      红框为session存储的中间件, 如果将它注释, 则django不能使用session

 

 

 

   2. 基础介绍 ---- Django 框架中进行 Session 存储时,默认支持 3 种存储方式,具体使用哪种可以在 settings.py 文件中通过 SESSION_ENGINE配置项进行配置,具体方式如下:

    1) 将session文件存储在数据库中(默认存储方式)

      Django框架内置了一个 session子应用,首次迁移时数据库中会生成一个django_session 表,默认时用来保存 session 数据:

# 默认session存储方式,不需要单独进行设置
SESSION_ENGINE='django.contrib.sessions.backends.db'

 

 

 

 

     2)将 session 数据存储在服务器缓存中(默认缓存就是服务器内存)

# 将 session 数据存储在服务器缓存中,默认缓存就是服务器内存
SESSION_ENGINE='django.contrib.sessions.backends.cache'

    3)将 session 数据进行混合存储(优先从缓存中存取,如果没有再从数据库中存取)

# 将 session 数据进行混合存储(优先从缓存中存取,如果没有再从数据库中存取)
SESSION_ENGINE='django.contrib.sessions.backends.cache_db'

   3. Redis存储session位置

    在实际的项目开发中,我们经常需要将 session数据存储到 redis 中。在 Django 项目中,对于这个需求我们可以借助 django-redis扩展包来进行实现,具体操作如下:

    1) 在项目虚拟幻环境中安装django-redis扩展包

pip install django-redis==4.12.1

 

     2)修改 settings,py 配置文件,进行CACHES 缓存配置和SESSION_ENGINE 存储配置

# Django框架的缓存存储配置,默认是服务器内存,此处将缓存配置为:redis
CACHES = {
    # 缓存空间
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        # 缓存空间的地址,此处是对应redis数据库的地址
        # 注意:这里 192.168.19.131 需要改成自己的 redis 数据库的IP
        "LOCATION": "redis://192.168.19.131:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

# Django框架的 Session 存储配置,此处是设置将 Session 数据存储到缓存中
# 注意:因为缓存已经设置为了redis,所有自然 session 数据就会存储到 redis 数据库中
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
# 此处是设置将 Session 数据存储到 CACHES 缓存的 default 空间中
SESSION_CACHE_ALIAS = "default"

 

   4. 修改templates页面,将是否记住用户名的复选框改为是否记住登录的复选框,内容如下:

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面模板</title>
</head>
<body>
    <form method="post" action="/login/">
        username:<input type="text" name="username"><br/>
        password:<input type="password" name="password"><br/>
        <input type="checkbox" name="remember" value="true">记住登录
        <input type="submit" value="登录">
    </form>
</body>
</html>

  5. 编辑子项目下的views.py 文件,修改 login View视图代码,将其恢复 Cookie记住用户名 之前的代码逻辑

# /login/
def login(request):
    """登录View视图函数"""
    if request.method == 'GET':
        # 返回登录页面
        return render(request, 'login.html')
    else:
        # 登录业务逻辑
        # 获取 username 和 password
        username = request.POST.get('username')
        password = request.POST.get('password')

        # 进行用户名和密码校验
        try:
            # 根据 username 和 password 查询对应的用户是否存在,即进行用户名和密码校验
            # get 方法默认会利用查询到的数据创建一个对应的模型类对象,并将这个模型对象返回
            user = User.objects.get(username=username, password=password)
        except User.DoesNotExist:
            # 如果 get 方法查询不到数据,会出现 `模型类.DoesNotExist` 异常
            # 用户名或密码错误
            return JsonResponse({'message': 'login failed'})
        else:
            # 用户名和密码正确
            return JsonResponse({'message': 'login success'})

  6. 修改 login View视图代码,在其中增加 Session记录登录用户状态的代码逻辑

# /login/
def login(request):
    """登录View视图函数"""
    if request.method == 'GET':
        # 返回登录页面
        return render(request, 'login.html')
    else:
        # 登录业务逻辑
        # 获取 username 和 password
        username = request.POST.get('username')
        password = request.POST.get('password')
        remember = request.POST.get('remember')

        # 进行用户名和密码校验
        try:
            # 根据 username 和 password 查询对应的用户是否存在,即进行用户名和密码校验
            # get 方法默认会利用查询到的数据创建一个对应的模型类对象,并将这个模型对象返回
            user = User.objects.get(username=username, password=password)
        except User.DoesNotExist:
            # 如果 get 方法查询不到数据,会出现 `模型类.DoesNotExist` 异常
            # 用户名或密码错误
            return JsonResponse({'message': 'login failed'})
        else:
            # 用户名和密码正确
            # Session 中保存当前登录用户的信息
            request.session['user_id'] = user.id
            request.session['username'] = user.username

            # 判断是否记住登录
            if remember != 'true':
                # 不记住登录,将 session的标识cookie 设置为浏览器关闭即失效
                request.session.set_expiry(0)

            return JsonResponse({'message': 'login success'})

  7. 在浏览器端清除浏览记录,然后结合登录页面进行登录测试,首先选择 记住登录 ,点击 登录,然后查看客户端响应提示:

  8. 修改 login View视图代码,增加判断用户是否已经登录的逻辑

# /login/
def login(request):
    """登录View视图函数"""
    # 判断是否已经登录
    username = request.session.get('username')

    if username:
        # username 在 session 中存在,则用户已登录
        return HttpResponse('%s用户已登录' % username)

    if request.method == 'GET':
        # 返回登录页面
        ...
    else:
        # 登录业务逻辑
        ...

  9. 重新访问登录页面进行测试,会提示用户已登录