【基于Django框架的在线教育平台开发-01】账号登录及退出登录功能开发

news2024/11/20 18:46:19

文章目录

    • 1 模型层开发
    • 2 视图层开发
    • 3 form表单验证
    • 4 配置urls.py
    • 5 模板层开发
    • 6 效果展示

1 模型层开发

用户数据表如下所示:

FieldTypeExtra
idintPrime Key & Auto Increment
passwordvarchar(128)
last_logindatetime(6)Allow Null
is_superusertinyint(1)
usernamevarchar(150)
first_namevarchar(150)
last_namevarchar(150)
emailvarchar(254)
is_stafftinyint(1)
is_activetinyint(1)
date_joineddatetime(6)
nick_namevarchar(50)
birthdaydateAllow Null
gendervarchar(6)
addressvarchar(100)
mobilevarchar(11)
imagevarchar(100)

由于Django内置了用户数据表,因此并没有新建数据表,而是选择重写默认用户数据表。由于后续诸多数据表都会用到add_time数据项,所以将该数据项暂时放在一个抽象类中,其他实体类继承于该抽象类。

这里提到的相关技术请参照:
【Django】模型层开发之重写模型类
【Django】模型层开发之创建并继承抽象模型类

from datetime import datetime

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

GENDER_CHOICES = (
    ("male", "男"),
    ("famale", "女"),
)


class BaseModel(models.Model):
    """
    用于存放多个模型共用的数据列,且不生成该类的数据表
    """
    add_time = models.DateTimeField(default=datetime.now, verbose_name="数据添加时间")

    class Meta:
        # 防止父类建表
        abstract = True


class UserProfile(AbstractUser):
    """
    重写用户模型类,继承自 AbstractUser
    """
    nick_name = models.CharField(max_length=50, verbose_name="昵称", default="")
    birthday = models.DateField(verbose_name="生日", null=True, blank=True)
    gender = models.CharField(verbose_name="性别", choices=GENDER_CHOICES, max_length=6)
    address = models.CharField(max_length=100, verbose_name="地址", default="")
    # mobile = models.CharField(max_length=11, unique=True, verbose_name="电话号码")
    mobile = models.CharField(max_length=11, verbose_name="电话号码")
    image = models.ImageField(verbose_name="用户头像", upload_to="head_image/%Y%m", default="default.jpg")

    class Meta:
        """
        对当前表进行相关设置
        """
        verbose_name = "用户信息"
        verbose_name_plural = verbose_name

    def __str__(self):
        """返回一个对象的描述信息"""
        if self.nick_name:
            return self.nick_name
        else:
            return self.username

2 视图层开发

整个视图层使用基于类的视图开发。
账号登录功能开发步骤如下:

  • GET方式访问该URL时,使用django内置参数is_authenticated,判断用户是否已经登陆过(检查cookies),若已登录则跳转至首页,反之跳转到登录界面;
  • POST方式访问时,按照如下步骤进行:
    • 使用django内置的form表单模块,验证数据是否有效,并获取表单数据,若数据无效则返回登陆页面;

    • 若表单数据不为空则使用django内置authenticate函数判断用户是否存在于数据库中;

      这里之所以使用django内置authenticate函数,而不使用user.objects.filter(username=username)的原因是:
      - 若只检查用户名或密码并不能完全查询到该用户;
      - 若同时验证用户名和密码,数据库中存储的密码为密文,用户输入的是明文,要经过一次加密才能验证,编码复杂;

    • 若查询到用户,则使用django内置的login()函数登录并使用HttpResponseRedirect()函数重定向到index界面,否则使用render()函数返回登陆页面,并回传错误信息和错误数据。

退出登录仅需要调用内置的logout()函数并重定向到主页(index.html)即可。

from django.shortcuts import render
from django.views.generic.base import View
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponseRedirect
from django.urls import reverse

from apps.operations.models import UserProfile
from apps.users.forms import LoginForm, DynamicLoginForm, RegisterGetForm, RegisterPostForm


class LogoutView(View):
    def get(self, request, *args, **kwargs):
        logout(request)
        return HttpResponseRedirect(reverse("index"))


class LoginView(View):
    def get(self, request, *args, **kwargs):
        if request.user.is_authenticated:
            return HttpResponseRedirect(reverse("index"))
        return render(request, "login.html")

    def post(self, request, *args, **kwargs):
        login_form = LoginForm(request.POST)  # 创建表单用于验证数据以及获取数据
        if login_form.is_valid():
            user_name = login_form.cleaned_data["username"]
            password = login_form.cleaned_data["password"]

            # 表单验证
            if not user_name:
                return render(request, "login.html", {"msg": "请输入用户名"})
            if not password:
                return render(request, "login.html", {"msg": "请输入密码"})
            
            # 用户查询(通过用户名和加密后的密码)
            user = authenticate(username=user_name, password=password)
            if user is not None:
                login(request, user)
                # 重定向url,调用reverse函数通过urlname来反向解析url
                return HttpResponseRedirect(reverse("index"))
            else:
                return render(request, "login.html", {"msg": "用户名或密码错误", "login_form": login_form})
        else:
            return render(request, "login.html", {"login_form": login_form})

3 form表单验证

django中自带form表单验证模块,我们只需要在forms.py文件中规定表单字段,然后在视图层中创建该表单对象并使用模块内置的is_valid()函数验证即可,验证中会若出现错误信息会放在form.errors对象中。例如:password小于6个字符,就会在form.errors.password对应的信息中提示该错误,模板层开发中会使用该参数。更多高级操作会在后续的功能开发中使用到。

注意:变量名必须与前端输入框的<name>标签保持一致。

from django import forms


class LoginForm(forms.Form):
    """
    实现表单验证功能
    """
    username=forms.CharField(required=True, min_length=2)
    password=forms.CharField(required=True, min_length=6)

4 配置urls.py

注意:配置urls时需要设置name参数,后续前端界面配置url跳转时会使用到该参数。

from apps.users.views import LoginView, LogoutView
urlpatterns = [
    path('login/', LoginView.as_view(), name="login"),  # 当前app的专属urls配置文件
    path('logout/', LogoutView.as_view(), name="logout"),
]

5 模板层开发

  1. 配置form表单提交方式为POST:method="post";配置form表单向登录url提交数据:action="{% url 'login' %}"login是urls.py配置中所设置的name参数,对应url:http://127.0.0.1:8000/login/
  2. 根据form表单验证中的报错信息高亮标注报错数据对应的输入框:在<input>标签的class属性中添加{% if login_form.errors.username %}errorput{% endif %}
  3. 显示报错信息。若form表单验证出错则显示其报错信息,否则显示视图层中回传的其余报错信息。
<div class="fl form-box">
    <h2>帐号登录</h2>
    <form action="{% url 'login' %}" method="post" autocomplete="off">
        <input type='hidden' name='csrfmiddlewaretoken' value='mymQDzHWl2REXIfPMg2mJaLqDfaS1sD5'/>
        <div class="form-group marb20 {% if login_form.errors.username %}errorput{% endif %}">
            <label>&nbsp;&nbsp;</label>
            <input name="username" id="account_l" type="text" placeholder="手机号/邮箱"
                   value="{{ login_form.username.value }}"/>
        </div>
        <div class="form-group marb8 {% if login_form.errors.password %}errorput{% endif %}">
            <label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label>
            <input name="password" id="password_l" type="password" placeholder="请输入您的密码"
                   value="{{ login_form.password.value }}"/>
        </div>
        <div class="error btns login-form-tips" id="jsLoginTips">
            {% if login_form.errors %}
                {% for key, error in login_form.errors.items %}
                    {{ error }}
                {% endfor %}
            {% else %}
                {{ msg }}
            {% endif %}
        </div>
        <div class="auto-box marb38">

            <a class="fr" href="forgetpwd.html">忘记密码?</a>
        </div>
        <input class="btn btn-green" id="jsLoginBtn" type="submit" value="立即登录 > "/>
        <input type='hidden' name='csrfmiddlewaretoken' value='5I2SlleZJOMUX9QbwYLUIAOshdrdpRcy'/>
        {% csrf_token %}
    </form>
    <p class="form-p">没有慕学在线网帐号?<a href="register.html">[立即注册]</a></p>
</div>

至此登录和退出登录功能开发完成,记得修改主页(index.html)的登录跳转按键相关属性。

6 效果展示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/686282.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

适用于 SAP 解决方案的 OpenText Extended ECM(企业内容管理)

适用于SAP 解决方案的 Extended ECM 概述 创建一种更好的将您的企业内容和企业应用程序连接起来工作方式&#xff0c;并从全面的数字内容管理平台中受益&#xff0c;该平台以产品化的方式无缝集成到任何 SAP 业务应用程序中&#xff0c;无论是在本地还是在云中。 SAP 解决方案…

Flutter 组件(二)文本 与 输入框组件

Flutter开发笔记 Flutter 组件&#xff08;二&#xff09;文本 与 输入框组件 - 文章信息 - Author: Jack Lee (jcLee95) Visit me at: https://jclee95.blog.csdn.netEmail: 291148484163.com. Shenzhen ChineAddress of this article:https://blog.csdn.net/qq_28550263/art…

第一章 计算机系统的概述①

一、操作系统概述 1、操作系统的概念&#xff08;什么是操作系统&#xff09; 概念&#xff1a;操作系统 (Operating System&#xff0c; 0s) 是指控制和管理整个计算机系统的硬件和软件资源&#xff0c;并合理地组织调度计算机的工作和资源的分配:以提供给用户和其他软件方便…

✅【值得收藏】超全期刊缩写查询网址

【SciencePub学术干货】英文论文写作中会插入参考文献&#xff0c;而参考文献中的期刊名称时常需要使用缩写。期刊缩写一般包括两种格式&#xff1a;JCR缩写和ISO缩写。比如 Journal of controlled release 杂志&#xff1a; 期刊名&#xff1a;JOURNAL OF CONTROLLED RELEASE…

力扣算法刷题Day47|周日总结:动态规划之背包问题

背包问题 〉题型分类 解题套路 〉动规五部曲 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 解题技巧 〉递推公式 问背包装满后的最大价值&#xff1a;dp[j] max(dp[j], dp[j - weight[i]] value[i]) …

跨库分页查询

背景 随着数据量的增大&#xff0c;数据库需要进行水平切分&#xff0c;例如通过业务主键id取模&#xff0c;使得数据均匀分布到不同的库中&#xff0c;随之而来的问题就出现跨库如何进行分页查询。 举例 select * from t_user order by time offset 200 limit 100 当在单库…

NXP i.MX 6ULL工业核心板规格书( ARM Cortex-A7,主频792MHz)

1 核心板简介 创龙科技SOM-TLIMX6U是一款基于NXP i.MX 6ULL的ARM Cortex-A7高性能低功耗处理器设计的低成本工业级核心板&#xff0c;主频792MHz&#xff0c;通过邮票孔连接方式引出Ethernet、UART、CAN、LCD、USB等接口。核心板经过专业的PCB Layout和高低温测试验证&#xf…

Jenkins在Ubuntu的安装问题

使用apt安装没有成功&#xff0c;各种报错。最后使用了离线安装方式。 1、安装jdk。和之前的安装jdk无异&#xff0c;增加一步 添加一个软链接 sudo ln -s /path/to/java/home/bin/java /usr/bin/java 2、下载deb包&#xff0c;然后安装 2.1、前置步骤&#xff0c;安装可能…

面向适航符合性的智能航电系统认证研究进展

摘要 民用飞机航电系统引入人工智能/机器学习技术会带来可信性、不确定性和可解释性等问题&#xff0c;有必要通过有效的符合性方法向公众与利益攸关方证实智能航电系统的适航安全性。首先&#xff0c;分析了智能航电系统的等级分类和应用现状&#xff0c;阐述了现有指南和标准…

three.js通过CubeTexture加载环境贴图,和RGBELoader加载器加载hdr环境贴图

一、使用CubeTexture进行环境贴图 1.CubeTexture使用介绍 Three.js中可以通过使用CubeTexture进行环境贴图&#xff0c;CubeTexture需要将6张图片&#xff08;正面、反面、上下左右&#xff09;包装成一个立方体纹理。下面是一个简单的例子&#xff1a; 首先需要加载六张贴图…

关于随机梯度下降算法及其改进方向

回归与分类等监督学习是机器学习中最常见的一类学习问题, 它提供了包含输入数据和目标数据的训练数据集。为了探讨输入与目标之间的关系&#xff0c;需要先建立含参数的表示模型&#xff0c;再通过最小化所有样本的平均损失函数来获得最优的参数, 此处的优化模型通常为经验风险…

【SpringMVC】统一异常处理 前后台协议联调 拦截器

1&#xff0c;统一异常处理 1. 问题描述 在讲解这一部分知识点之前&#xff0c;我们先来演示个效果&#xff0c;修改BookController类的getById方法 GetMapping("/{id}") public Result getById(PathVariable Integer id) {//手动添加一个错误信息if(id1){int i …

那些曾经考过的turtle绘图题(16~20)

【编程实现绘图 -16】 使用turtle绘制如右图1中所示的图形。 上边是一个红色轮廓、黄色填充的边长为300的等边三角形,下边是一个绿色填充、半径为150的半圆。 要求: 1)画布背景为白色,等边三角形为红色轮廓、黄色填充; 2)半圆为绿色填充、且与等边三角形在底边的中点处相…

OpenCV——总结《车牌识别》之《常用的函数介绍》

1. cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10))element cv2.getStructuringElement(shape, ksize[, anchor])用于创建形态学操作的结构元素&#xff08;structuring element&#xff09;。 参数解释&#xff1a; shape&#xff1a;结构元素的形状&#xff0c;可以…

k近邻算法

文章目录 一、K近邻算法(K Nearest Neighbor algorithm, KNN)1.概念2.流程3.问题——不能用来图像分类1&#xff09;图像分类2&#xff09;为什么不能用来图像分类3&#xff09;数据库样例&#xff1a;CIFAR-10 二、HEU的K近邻算法1.概念2.伪代码3.k近邻算法是非线性分类算法4.…

java项目之教学视频点播系统ssm

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的教学视频点播系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风歌&…

SVM支持向量机理解_KKT条件_拉格朗日对偶_SMO算法代码

目录 一、支持向量机基本型&#xff08;线性可分&#xff09; 1.1 问题描述 1.2 参考资料 二、KKT条件 2.1 KKT条件的几个部分 2.1.1 原始条件 2.1.2 梯度条件 2.1.3 松弛互补条件 2.1.4 KKT条件小结 2.2 参考资料 三、对偶形式 3.1 由原始问题到对偶问题 3.2 对偶…

ubuntu双系统安装

1. 下载系统 国内镜像 http://mirrors.ustc.edu.cn/ubuntu-releases/2. U盘启动盘 Rufus 软件 制作U盘启动盘 Rufus 链接 https://rufus.en.softonic.com/3. 磁盘中准备一定未分配磁盘 我准备了100G 4. BIOS启动项选择为usb启动&#xff08;每个品牌进BIOS不同&#xff0…

win下 Nginx.conf 路径配置注意事项(win)

win下 Nginx.conf 路径配置注意事项 文章目录 可使用win绝对路径路径不能包含中文路径不能包含空格路径中的"\n"会被识别成换行贴一段正确配置的Nginx.conf代码 可使用win绝对路径 网上有种说法是win下Nginx不能设置绝对路径&#xff0c;但我在Nginx-1.24.0下是设置…

在Windows11中安装WSL2(Ubuntu20.04)并配置Anaconda环境

在Windows11中安装WSL2(Ubuntu20.04)并配置Anaconda环境 文章目录 在Windows11中安装WSL2(Ubuntu20.04)并配置Anaconda环境说在前面1. 检查开启CPU虚拟化和虚拟机平台2. 安装Ubuntu20.043. Vscode连接WSL2(Ubuntu20.04)4. Anaconda开发环境的搭建5. Vscode 访问 notebook结尾 说…