python-Django项目实战-注册与登录

用户数据表模型

用户表

用户表由Django内置模型User扩展而成。

表字段 字段类型 含义
id Int类型,长度为11 主键
password Varchar类型,长度为128 用户密码
last_login Datetime类型,长度为6 上次登录的时间
is_superuser Tinyint类型,长度为1 超级用户
username Varchar类型,长度为150 用户名
first_name Varchar类型,长度为30 用户的名字
last_name Varchar类型,长度为150 用户的姓氏
email Varchar类型,长度为254 邮箱地址
is_staff Tinyint类型,长度为1 登录Admin权限
is_active Tinyint类型,长度为1 用户的激活状态
date_joined Datetime类型,长度为6 用户创建的时间
qq Varchar类型,长度为20 用户的QQ号码
weChat Varchar类型,长度为20 用户的微信号码
mobile Varchar类型,长度为11 用户的手机号码

用户表创建

  • 用户表可以自己创建,在Django也可以由内置模型User扩展而成。

  • AbstractUser 是 Django 中的一个抽象模型类,用于扩展用户模型。在 Django 的身份验证系统中,用户模型是一个很重要的核心部分。AbstractUser 提供了一些基本的字段和方法,可以用来创建自定义的用户模型。

    使用 AbstractUser 非常简单,你只需要在你的 Django 项目中创建一个新的模型类,并继承自 AbstractUser。然后,你可以在该模型中添加额外的字段和方法,以满足你的需求。

  • 它与歌曲信息表并无数据关联,因此将用户表的模型定义在项目应用user的models.py中。

代码如下:

python 复制代码
from django.contrib.auth.models import AbstractUser
​
class MyUser(AbstractUser):
    qq = models.CharField('QQ号码', max_length=20)
    weChat = models.CharField('微信账号', max_length=20)
    mobile = models.CharField('手机号码', max_length=11, unique=True)
    # 设置返回值
    def __str__(self):
        return self.username

AbstractUser 类中默认创建了以上字段,只需要基础增加所需字段即可

setting中指定用户表

ini 复制代码
AUTH_USER_MODEL='user.MyUser'

最后对定义好的模型执行数据迁移。

python manage.py makemigrations
python manage.py migrate

运行异常解决

在课程中,初始化项目已经创建完成用户表,所以不能在创建。

原因是Django中有一个原生的User模型类,admin的模型依赖这个模型类,由于前面一个应用中的模型类User继承了AbstractUser类,所以提示这个错误。

其他方法就是对数据库备份,删除数据库重新创建。迁移并且还原数据库

或者经adminapp先进行注释

注册与登录

用户注册与登录是用户管理的必备功能之一,没有用户的注册与登录,就没有用户管理的存在。只要涉及用户方面的功能,我们都可以使用Django内置的Auth认证系统实现。

用户管理由项目应用user实现,在项目应用user中创建文件forms.py

该文件用于定义表单类MyUserCreationForm,由表单类实现用户注册功能。打开user的forms.py文件,并且定义表单类MyUserCreationForm,代码如下:

python 复制代码
from django.contrib.auth.forms import UserCreationForm
from .models import MyUser
from django import forms
​
​
class MyUserCreationForm(UserCreationForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['password1'].widget = forms.PasswordInput(
            attrs={'class': 'txt tabInput', 'placeholder': '密码,4-16位数字/字母/符号(空格除外)'})
        self.fields['password2'].widget = forms.PasswordInput(attrs={'class': 'txt tabInput', 'placeholder': '重复密码'})
​
    

表单类MyUserCreationForm在父类UserCreationForm的基础上实现两个功能:添加模型MyUser的新增字段和设置表单字段的CSS样式,功能说明如下:

(1)添加模型MyUser的新增字段:在嵌套类Meta的fields属性中设置新增字段即可,添加的字段必须是模型字段并且以元组或列表的形式表示。

(2)设置表单字段的CSS样式:设置表单字段mobile、username、password1和password2的attrs属性。表单字段mobile和username是模型MyUser的字段,在嵌套类Meta中重写widgets属性即可,而password1和password2是父类UserCreationForm自定义的表单字段,必须重写初始化方法__init__设置字段的CSS样式。

路由

完成表单类MyUserCreationForm的定义,下一步在user的urls.py中定义用户注册与登录的路由信息,我们将用户注册与登录定义在路由信息中,定义过程如下:

javascript 复制代码
from django.urls import path, include
from . import views
urlpatterns = [
    path('login/', views.login_view, name='login'),
    path('register/', views.register, name='register'),
]

视图

路由login将实现用户登录功能,register将完成注册视图。路由的HTTP请求由视图函数loginView负责接收和处理,在user的view.py中定义视图函数loginView,代码如下:

python 复制代码
from django.contrib.auth.hashers import check_password
from django.db.models import Q
from django.shortcuts import render, redirect
from django.shortcuts import reverse
​
from user.models import *
from .forms import MyUserCreationForm
​
​
def register(request):
    if request.method == 'POST':
        form = MyUserCreationForm(request.POST)
        if form.is_valid():  # 判断表单数据是否合格
            form.save()  # 将用户信息存储到数据库
            return redirect('/user/login')
    else:
        form = MyUserCreationForm()
    return render(request, 'register.html', locals())
​
​
# 用户注册与登录 2ee2r45y6
def login_view(request):
    data = {}
    if request.method == 'POST':
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
​
        user_data = MyUser.objects.filter(username=username)
        if user_data:
            user = user_data.first()
            from django.contrib.auth.hashers import check_password
            if check_password(password, user.password):
                login(request, user)
                return redirect(reverse('home'))
            else:
                data['tips'] = '密码错误'
        else:
            data['tips'] = '用户不存在'
        # 账号是否存在 密码是否正确 session 重定向
        return render(request, 'login.html', data)
​
    if request.method == 'GET':
        return render(request, 'login.html', {})
​
​

模板

登录模板

xml 复制代码
{% extends "base.html" %}
{% load static %}
​
{% block body %}
​
​
    <!-- 登录注册版块 -->
    <div id="unauth_main" class="login-regist">
        <div class="login-box switch_box">
            <div class="title">用户登录</div>
            <form id="loginForm" class="formBox" action="" method="post">
                {% csrf_token %}
                <div class="itembox user-name">
                    <div class="item">
                        <input type="text" name="loginUser" placeholder="用户名或手机号" class="txt tabInput">
                    </div>
                </div>
                <div class="itembox user-pwd">
                    <div class="item">
                        <input type="password" name="password" placeholder="登录密码" class="txt tabInput">
                    </div>
                </div>
                {% if tips %}
                    <div>提示:<span>{{ tips }}</span></div>
                {% endif %}
                <div id="loginBtnBox" class="login-btn">
                    <input id="J_LoginButton" type="submit" value="马上登录" class="tabInput pass-btn"/>
                </div>
                <div class="pass-reglink">
                    没有账号?
                    <a class="switch" href="{% url 'register' %}">免费注册</a>
                </div>
            </form>
        </div>
    </div>
​
{% endblock %}

(1)标注①使用HTML语言编写用户登录表单,表单设置了两个文本输入框,分别命名为loginUser和password。视图函数loginView通过判断loginUser文本输入框的数据来识别当前操作。

注册模板

javascript 复制代码
{% extends "base.html"  %}
{% load static %}
​
{% block body  %}
<h1>用户注册</h1>
    <form method="POST" action="{% url 'register' %}">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">注册</button>
    </form>
{% endblock  %}

(2)标注②使用表单对象user生成用户注册表单,将表单类MyUserCreationForm的表单字段生成相应的文本输入框。

注销登录

路由

ini 复制代码
urlpatterns = [
    # 其他URL路由
    path('logout/', views.logout_view, name='logout'),
]

模板中如果需要可以使用以下

ini 复制代码
<a href="{% url 'logout' %}">退出登录</a>

视图代码:

python 复制代码
from django.contrib.auth import logout
​
def logout_view(request):
    logout(request)
    # 进一步重定向到某个页面,例如登录页面
    return redirect('login')

如果要设置session存在时间

ini 复制代码
# 设置 Session 的 Cookie 生命周期为 1 小时
SESSION_COOKIE_AGE = 3600
#默认值2周的时间
SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
​
# 设置 Session 在浏览器关闭时过期
SESSION_EXPIRE_AT_BROWSER_CLOSE = True  # 它的模认值是 False,即表示不开启。
相关推荐
拉玛干6 分钟前
社团周报系统可行性研究-web后端框架对比-springboot,django,gin
数据库·python·spring·golang
Yan-英杰35 分钟前
Encountered error while trying to install package.> lxml
开发语言·python·pandas·pip·issue
RS&38 分钟前
python学习笔记
笔记·python·学习
AI原吾38 分钟前
解锁自动化新境界:KeymouseGo,让键盘和鼠标动起来!
运维·python·自动化·计算机外设·keymousego
卡卡_R-Python39 分钟前
海洋气象编程工具-Python
开发语言·python
北愚41 分钟前
Scrapy爬虫实战——某瓣250
python·scrapy
.别止步春天.43 分钟前
Python中lambda表达式的使用——完整通透版
数据结构·python·算法
RaidenQ1 小时前
2024.9.20 Python模式识别新国大EE5907,PCA主成分分析,LDA线性判别分析,GMM聚类分类,SVM支持向量机
python·算法·机器学习·支持向量机·分类·聚类
_平凡之路_1 小时前
解决ubuntu22.04 gnome-terminal 无法启动的问题
linux·运维·python
豆本-豆豆奶1 小时前
23个Python在自然语言处理中的应用实例
开发语言·python·自然语言处理·编程语音