Django 项目实践 —— 可重用注册登录系统 (1)

Django 项目实践 —— 可重用注册登录系统 (1)

目录

可重用注册登录系统

可重用注册登录系统

搭建项目环境

创建应用

安装ignore 插件

git提交项目代码到本地仓库

设计数据库模型

用户表分析

文件的配置

生成迁移脚本并写入数据库

数据库模型后台管理

路由与视图函数框架搭建

路由设计

访问策略

路由配置

模板template的配置

前端界面设计与优化

完善登录的视图函数

html和视图函数交互的完善

session会话与登录的视图函数


可重用注册登录系统


  • 注册(邮箱注册,手机,微信,QQ)
  • 登录
  • 注销

搭建项目环境


创建应用

  • 创建Django项目
  • 设置时区和语言
  • 创建app
python manage.py startapp login
  • 数据库表生成
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser

  • 启动开发服务器
# 启动服务,指定8080 端口
python manage.py runserver 8080

  • 浏览器访问,检测是否成功?(第一步完美搞定)

访问网址: http://127.0.0.1:8080/

访问网址: http://127.0.0.1:8080/admin/


安装ignore 插件

过滤某些不想提交到git 本地库的文件


git提交项目代码到本地仓库

$ git init
# 安装插件.ignore, 并生成python上传git项目需要忽略内容的文件.gitignore
$ git add * # 添加修改到暂存区
$ git commit -m "搭建项目开发环境" # 将暂存区的代码提交到本地git仓库
$ git log # 查看历史提交记录

 


设计数据库模型


用户表分析

作为一个用户登录和注册项目,需要保存的都是各种用户的相关信息。很显然,我们至少需要一张用户 表User,在用户表里需要保存下面的信息:

  • 用户名(name): 必填,最长不超过128个字符且唯一(unique)
  • 密码(password): 必填,最长不超过256个字符
  • 邮箱地址(email): 使用Django内置的邮箱类型且唯一
  • 性别(gender): 性别, 使用choice,只能选择男或者女或者未知,默认为未知;
  • 创建时间(create_time): 用户创建时间

注意点: auto_now_add=True时为添加时的时间,更新对象时不会有变动。

  • 修改时间(modify_time):用户最后一次修改时间

注意点: auto_now=True无论是你添加还是修改对象,时间为你添加或者修改的时间。

  • 最后一次登录时间(last_login_time): 最后一次登录时间

注意点:null=True的话,数据库中该字段是NULL,即允许空值

注意点:blank=False(默认)的话,字段没被赋值则会抛错;和数据验证(表单验证等)有 关


文件的配置

数据库模型文件(login/models.py)

from django.db import models
# 定义数据库模型

# Create your models here.

# appname_siteuser
class SiteUser(models.Model):
    """用户的数据库模型,注册/登陆需要"""
    # gender_choice 性别
    gender_choice = (
        (0, "未知"),
        (1, "男"),
        (2, "女"),
    )
    # 姓名,字符串类型, unique=True (唯一标识)
    name = models.CharField(max_length=128, unique=True, verbose_name="用户名")
    # 密码
    password = models.CharField(max_length=256, verbose_name="密码")
    # 邮件
    email = models.EmailField(unique=True, verbose_name="电子邮件")
    # 性别,默认0,未知
    gender = models.IntegerField(choices=gender_choice, default=0, verbose_name="性别")
    # 创建时间,
    # auto_now_add=True时为添加时的时间,更新对象时不会有变动。
    # auto_now=True无论是你添加还是修改对象,时间为你添加或者修改的时间。
    create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    # 最后一次更改时间
    modify_time = models.DateTimeField(auto_now=True, verbose_name="最后一次修改时间")
    # 最后一次登录时间
    # null针对数据库层面的, blank针对表单的
    last_login_time = models.DateTimeField(null=True, blank=True, verbose_name="最后一次登陆时间")

    # 友好展示
    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "网站用户管理"
        verbose_name_plural = verbose_name

保存到本地 git 库

设置数据库后端

Django支持MySQL, Sqlite, oracle等数据库, 此处选择默认的sqlite,不做修改。

 

注册app(loginRegister/setting.py)

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'login',    # 修改的内容
]

生成迁移脚本并写入数据库

生成迁移脚本并写入数据库

python manage.py makemigrations   # 生成迁移文件
python manage.py migrate   # 将迁移脚本的内容写入数据库并创建数据库表

 测试是否成功 打开数据库文件db.sqlite3, 查看是否有数据库表login_siteuser,如果有,则操作成功。


数据库模型后台管理

数据库模型后台管理(login/admin.py)

from django.contrib import admin

# Register your models here.

from login.models import SiteUser


class SiteUseradmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'gender']
    list_filter = ['gender', 'create_time']
    search_fields = ['name']


admin.site.register(SiteUser, SiteUseradmin)

保存到本地 git库

查看本地 git 库提交日志

浏览器访问,检测是否成功?(完美搞定)

访问网址: http://127.0.0.1:8080/admin/


路由与视图函数框架搭建


路由设计

URL视图views模板功能
/index/login.views.indexindex.html首页
/login/login.views.loginlogin.html登陆页面
/register/login.views.registerregister.html注册界面
/logout/login.views.logout无需返回页面登出界面

 

 

 

 

 

 


访问策略

  • 未登录人员,不论是访问index还是login和logout,全部跳转到login界面
  • 已登录人员,访问login会自动跳转到index页面
  • 已登录人员,不允许直接访问register页面,需先logout
  • 登出后,自动跳转到login界面

 


路由配置

主路由配置文件(loginRegister/urls.py)

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('login.urls')),
]

子路由配置文件(login子应用的)(login/urls.py  (新建))

from django.contrib import admin
from django.urls import path, include
from login import views

urlpatterns = [
    path('index/', views.index, name='index'),
    path('login/', views.login, name='login'),
    path('register/', views.register, name='register'),
    path('logout/', views.logout, name='logout'),
]

视图函数的配置(login/views.py)

# login/views.py
from django.shortcuts import render, redirect
# Create your views here.

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

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

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

def logout(request):
    pass
    # redirect: 重定向(跳转)
    return redirect('/login/')

模板template的配置

templates/login/index.html(新建)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>这是首页的模拟界面</h1>
</body>
</html>

templates/login/login.html(新建)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>
<h1>用户登录</h1>
<form>
    用户名: <input type="text" placeholder="username"><br/>
    密码: <input type="password" placeholder="password"><br/>
    <input type="submit" value="登录">
</form>
</body>
</html>

templates/login/register.html(新建)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册界面</title>
</head>
<body>
<h1>用户注册</h1>
<form>
    用户名: <input type="text" placeholder="username"><br/>
    电子邮箱: <input type="email" placeholder="email"><br/>
    密码: <input type="password" placeholder="password"><br/>
    确认密码: <input type="password" placeholder="password"><br/>
    <input type="submit" value="注册">
</form>
</body>
</html>

保存到本地git 库

测试是否成功

浏览器访问,检测是否成功?(第一步完美搞定)

  • 访问网址: http://127.0.0.1:8080/index/
  • 访问网址: http://127.0.0.1:8080/login/
  • 访问网址: http://127.0.0.1:8080/register/

 


前端界面设计与优化


在颜值即正义的年代,但没有CSS和JS,样子真的令人无法接受。 然而,大多数使用Django的人都不具备多高的前端水平,通常也没有专业的前端工程师配合,自己写的 CSS和JS却又往往惨不忍睹。怎么办?没关系,我们有现成的开源前端CSS框架!Bootstrap4就是最好 的CSS框架之一!

Bootstrap核心汇总:

首页美化

# template/login/index.html



<!doctype html>
<html lang="zh-CN">
<head>
    <!-- 必须的 meta 标签 -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap 的 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"
          integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">

    <title>首页</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <a class="navbar-brand" href="#">主页</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item active">
                <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Link</a>
            </li>
            <li class="nav-item dropdown">
                <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown"
                   aria-haspopup="true" aria-expanded="false">
                    Dropdown
                </a>
                <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                    <a class="dropdown-item" href="#">Action</a>
                    <a class="dropdown-item" href="#">Another action</a>
                    <div class="dropdown-divider"></div>
                    <a class="dropdown-item" href="#">Something else here</a>
                </div>
            </li>
            <li class="nav-item">
                <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
            </li>
        </ul>
        <form class="form-inline my-2 my-lg-0">
            <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
            <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
        </form>
        <ul class="navbar-nav">
            <li class="nav-item">
                <a class="nav-link" href="/logout/">登出</a>
            </li>

            <li class="nav-item">
                <a class="nav-link" href="/index/">{{ request.session.username }}</a>
            </li>
        </ul>
    </div>
</nav>

<h1>你好, {{ request.session.username }}, 这是首页的模拟界面</h1>


<!-- JavaScript 文件是可选的。从以下两种建议中选择一个即可! -->

<!-- 选项 1:jQuery 和 Bootstrap 集成包(集成了 Popper) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"
        integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
        crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-LCPyFKQyML7mqtS+4XytolfqyqSlcbB3bvDuH9vX2sdQMxRonb/M3b9EmhCNNNrV"
        crossorigin="anonymous"></script>

<!-- 选项 2:Popper 和 Bootstrap 的 JS 插件各自独立 -->
<!--
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.min.js" integrity="sha384-gRC4eoaRyQ8xv2X6Mnf+eOIrtON3wId3dAkwO0HQX26OrFBoLpjX/XWOJacSiZhL" crossorigin="anonymous"></script>
-->
</body>
</html>

 


完善登录的视图函数


html和视图函数交互的完善

  • 修改1. 有message信息则显示, 没有就不显示。
  • 修改2: 提交登录信息时, 以post方法提交给/login/对应的是视图函数处理。
  • 修改3: Django提供了csrf防攻击的机制, 添加该信息则可顺利访问登陆界面
  • 修改4:name="username"指定表单内容存储的key值名称, eg: {"username":"你填的用户 名","password":"你填的密码" }

templates/login/login.html

<div class="col-sm">
    <h3 style="text-align: center">用户登录</h3>
    # 修改1. 有message信息则显示, 没有就不显示。
    {% if message %}
    <div class="alert alert-warning" role="alert">
    <    strong>登录失败!</strong> {{ message }}

    </div>
    {% endif %}
    # 修改2: 提交登录信息时, 以post方法提交给/login/对应的是视图函数处理。
    <form action="/login/" method="post">
        # 修改3: Django提供了csrf防攻击的机制, 添加该信息则可顺利访问登陆界面
        {% csrf_token %}
        <div class="form-group">
            <label>用户名</label>
            # 修改4:name="username"指定表单内容存储的key值名称, eg:{"username":"你填的用户名"}
            <input type="text" class="form-control" name="username">
        </div>
        <div class="form-group">
            <label>Password</label>
            <input type="password" class="form-control" name="password">
            <small class="form-text text-muted">密码必须是字母、数字或者特殊符号组成</small>
        </div>
        <a href="/register/" class="text-success">
            <ins>新用户注册</ins>
        </a>
        <button type="submit" class="btn btn-primary float-right">登录</button>
    </form>
</div>

视图函数的完善(login/views.py)

# login/views.py
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username').strip()
        password = request.POST.get('password').strip()
        # print(username, password)
        if username and password:
            user = SiteUser.objects.filter(name=username,password=password).first()
            if user:
                return redirect('/index/')
            else:
                message = "用户名或者密码错误"
                return render(request, 'login/login.html',{'message':message})
        else:
            message = "非法的数据信息"
            return render(request, 'login/login.html', {'message': message})
    return render(request, 'login/login.html')

保存到本地git 库

浏览器访问,检测是否成功?

  • 访问网址: http://127.0.0.1:8080/login/
  • 填写正确的用户名和密码/错误的用户名和密码测试是否为期待的效果。

 


session会话与登录的视图函数

登录成功, 存储登录的用户信息到session中(login/views.py)

def login(request):
    if request.method == 'POST':
        username = request.POST.get('username').strip()
        password = request.POST.get('password').strip()
        # print(username, password)
        if username and password:
            user = SiteUser.objects.filter(name=username,password=password).first()
            if user:
                # ------------核心修改的内容开始
                request.session['is_login'] = True
                request.session['user_id'] = user.id
                request.session['username'] = user.name
                # --------------核心修改的内容结束
                return redirect('/index/')
            else:
                message = "用户名或者密码错误"
                return render(request, 'login/login.html',{'message':message})
        else:
            message = "非法的数据信息"
            return render(request, 'login/login.html', {'message': message})
    return render(request, 'login/login.html')

登出时,清空session信息(login/views.py)

def logout(request):
    # 如果状态不是登录状态,则无法登出。
    if request.session.get('is_login'):
        request.session.flush() # 清空session信息
    return redirect('/login/')

在首页添加登出的超链接并测试(templates/login/index.html)

# 核心代码如下:
    <h1>你好, {{ request.session.username }}, 这是首页的模拟界面</h1>
    <a href="/logout/"><strong style="font-size: 20px">登出</strong></a>

浏览器访问,检测是否成功?

访问网址: http://127.0.0.1:8080/index/

项目地址: https://gitee.com/half-summer/loginregister

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值