015 Django 云笔记项目(可以略过)

云笔记项目

文章目录

  • 云笔记项目
    • 一般项目组成成员
    • 功能拆解
    • 初始化项目
    • 用户模型类设计
      • 创建我们的 User 模型类
    • 用户注册 第一版
    • 用户注册 第二版
      • 要求 1 密码问题
        • 如何在 python 中使用哈希算法
      • 要求2 高并发问题
      • 要求3 注册免登录一天
    • 用户登陆
      • 用户进入登陆页面的时候判断是否在cookies有效期内
    • 网站首页
      • 我们直接使用模板来判断页面
    • 退出登陆
    • 笔记模型类

015 Django 云笔记项目(可以略过)_第1张图片

一般项目组成成员

  • 产品/运营经理 : 负责产品功能细节的把控
  • 开发
    • 前端 - 负责显示部分内容的开发 [多]
    • 后端 - 负责服务器部分的功能开发 [少]
  • 运维 - 管理 linux 服务器,组件化配置,安全问题
  • 测试 - 负责找出产品功能的问题[bug]
  • 美工 - 负责产品素材方面的绘制

功能拆解

一般情况下由产品经理负责

  • 用户模块
    • 注册 - 成为用户平台
    • 登陆 - 校验用户身法
    • 退出登陆 - 退出登陆状态
  • 笔记模块
    • 查看笔记列表 - 查
    • 创建新笔记 - 增
    • 修改笔记 -该
    • 删除笔记 -删

初始化项目

创建一个 tedu_note项目,然后初始化下列配置

django-admin startproject tedu_note
  • 禁止csrf
    • 015 Django 云笔记项目(可以略过)_第2张图片
  • 语言更改
    • image-20220625174644866
  • 时区更改
    • image-20220625174632544
  • 数据库配置
    • 015 Django 云笔记项目(可以略过)_第3张图片
  • 创建/注册应用 user
    • image-20220625174741790
    • 015 Django 云笔记项目(可以略过)_第4张图片

用户模型类设计

创建我们的 User 模型类

from django.db import models

# Create your models here.
class User(models.Model):
    username = models.CharField("用户名",max_length=30,unique=True)
    password = models.CharField("密码",max_length=32)
    
    # 下面这两条网站都是每个模型必须要给的
    create_time = models.DateTimeField("创建时间",auto_now_add=True) # 只有当我们第一次更新的时候才会写入
    update_time = models.DateTimeField("更新时间",auto_now=True) # 每一次更新都会重置时间
    
    def __str__(self):
        return f'{self.username} - {self.create_time} - {self.update_time}'

用户注册 第一版

  • url : /user/reg
  • 视图函数: reg_view
  • 模板位置: templates/user/register.html
  • 界面样式
    • 015 Django 云笔记项目(可以略过)_第5张图片
  1. 书写 register.html 内容
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    <form method="post" action="/user/reg">
        <p>用户名 <input type="text" name="username">p>
        <p>密码 <input type="text" name="password">p>
        <p>重复你的密码 <input type="text" name="password2">p>
        <button type="submit" value="reg">注册button>

    form>
body>
html>

015 Django 云笔记项目(可以略过)_第6张图片

  1. 写视图文件
from django.http import HttpResponse
from django.shortcuts import render
from .models import User


# Create your views here.

def reg_view(request):
    if request.method == "GET":
        return render(request, 'user/register.html')
    
    if request.method == "POST":
               
        username = request.POST.get('username')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        
        # 检测是否为空
        if username == '' or password == '':
            return HttpResponse("账户名或者密码不能为空!")
        
        # 检测两次密码是否一致
        if password != password2:
            return HttpResponse("两次密码输入不一致")
        
        # 检测用户名是否可用
        old_user = User.objects.filter(username=username)
        if old_user:
            return HttpResponse(f"当前账户名 {username} 已经有人注册")
        
        # 如果都没出错就插入数据
        User.objects.create(username=username,password=password)
        return HttpResponse("注册成功!")
  1. 写 url.py 路由文件
# 主 urls.py 内容
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('user/',include("user.urls"))
]
# 子 urls.py 内容
from django.urls import path
from . import views

urlpatterns = [
    path('reg', views.reg_view)
]
  1. 查看我们的页面

015 Django 云笔记项目(可以略过)_第7张图片

用户注册 第二版

我们现在新增了 3 个需求

  1. 密码能够密文化,防止数据库泄露
  2. 插入问题[高并发的时候]
  3. 要求注册后就免登录一天

要求 1 密码问题

我们可以使用 哈希算法,给明文然后计算出一段定长的不可逆的值(md5, sha-256)

  • 哈希算法特点
    • 定长输出:不管明文输入长度为多少,哈希值都是定长的,md5 - 32为16进制
    • 不可逆:无法反向计算出对应的明文
    • 雪崩效应:输入只要发出一点改变,输出发生大变化
  • 常用使用场景
    • 密码保存
    • 网络传递文件的时候文件校对

如何在 python 中使用哈希算法

import hashlib

# 选择使用的哈希算法
m = hashlib.md5()

# 输入我们的值(注意需要在前面加上 b 前缀,因为我们输入的需要是一个字节码)
m.update(b'13829242002')

# 获取我们的16进制摘要
m.hexdigest()

我们现在就可以开始修改我们的密码保存,来让我们能够存入一个密文的密码

def reg_view(request):
    if request.method == "GET":
        return render(request, 'user/register.html')
    
    if request.method == "POST":
               
        username = request.POST.get('username')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        
        # 检测是否为空
        if username == '' or password == '':
            return HttpResponse("账户名或者密码不能为空!")
                
        # 检测两次密码是否一致
        if password != password2:
            return HttpResponse("两次密码输入不一致")
        
        # 检测用户名是否可用
        old_user = User.objects.filter(username=username)
        if old_user:
            return HttpResponse(f"当前账户名 {username} 已经有人注册")
        
        # 插入前对密码进行密文的处理
        m = hashlib.md5()
        m.update(password.encode())
        password_m = m.hexdigest()
        
        # 如果都没出错就插入数据
        User.objects.create(username=username,password=password_m)
        return HttpResponse("注册成功!")

015 Django 云笔记项目(可以略过)_第8张图片

015 Django 云笔记项目(可以略过)_第9张图片

要求2 高并发问题

我们在正式的环境中,因为有多个人可能会同时访问我们的数据库,所有唯一索引有可能会报错,我们现在需要使用 try 语句来防止我们的程序报错

  • 原来
# 如果都没出错就插入数据
User.objects.create(username=username,password=password_m)
return HttpResponse("注册成功!")
  • 修改后
# 如果都没出错就插入数据
try:
    User.objects.create(username=username,password=password_m)
    return HttpResponse("注册成功!")
except Exception as e:
    print(e)
    return HttpResponse("当前用户名已经被注册!")

要求3 注册免登录一天

015 Django 云笔记项目(可以略过)_第10张图片

# 免登陆一天
request.session['username'] = username
request.session['uuid'] = user.id

我们的 是否记住我勾选之后我们的提交请求就会多出来一项remember=on,我们只需要判断我们的 request.POST 中有没有这个键即可

  • 判断勾选了记住我,我们给用户一个 cookies
# 如果用户点击长时间记住我(保存3天)
        resp = HttpResponse("登陆成功!")
        if 'remember' in request.POST:
           resp.set_cookie('username',username,3600*24*3)
           resp.set_cookie('uuid',user.id, 3600*24*3)
        
        return resp
GET请求
POST请求
当前是GET请求
用户勾选记住我
用户没有勾选记住我
有session
没有session
有cookies
没有cookies
检查数据库是否有session
检查是否有Cookie
重新存入session到服务器
返回登录页面
向数据库存入session
执行正常登陆流程
用户是否勾选了记住我
向浏览器存入cookies
主页
用户进入登陆页面
判断当前是POST还是GET

用户登陆

015 Django 云笔记项目(可以略过)_第11张图片

用户进入登陆页面的时候判断是否在cookies有效期内

  • 原代码
if request.method == "GET":
        return render(request,'user/login.html')
  • 修改后
if request.method == "GET":
        # 检查 session
        if request.session.get('username') and request.session.get('uuid'):
            return HttpResponse("已登陆,即将返回主页")
        
        # 检查 cookies
        c_username = request.COOKIES.get('username')
        c_uuid = request.POST.get('c_uuid')
        if c_uuid and c_username:
            # 重新写入新的 session 到我们的数据库
            request.session['username'] = c_username
            request.session['uuid'] = c_uuid
            
            return HttpResponse("已登陆,即将返回主页")
        return render(request,'user/login.html')

网站首页

015 Django 云笔记项目(可以略过)_第12张图片

我们直接使用模板来判断页面

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
head>
<body>
    {% if request.session.username %}
    <p> 欢迎 {{request.session.username}} p>

    {% else %}
        {% if request.cookie.username %}
        <p> 欢迎 {{request.cookie.username}}p>

        {% else %}
        <p><a href="/user/login">登陆a>p>
        <p><a href="/user/reg">注册a>p>
        
        {% endif %}}
    
    {% endif %}

body>
html>

015 Django 云笔记项目(可以略过)_第13张图片

退出登陆

015 Django 云笔记项目(可以略过)_第14张图片

  1. 视图修改
def logout_view(request):
    # 清除我们的 session 和 cookie 并且返回登陆页面
    del request.session['username']
    del request.session['uuid']
    
    response = HttpResponseRedirect(reverse('home'))
    
    response.delete_cookie('username')
    response.delete_cookie('uuid')
    
    return response
  1. 修改一下HTML
  2. 查看网页

015 Django 云笔记项目(可以略过)_第15张图片

笔记模型类

class Note(models.Model):
    title = models.CharField("标题",max_length=100)
    content = models.TextField("内容")
    create_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

这个练习与之前的练习冲突,请前往查看图书管理练习

你可能感兴趣的:(Django,django,python,后端)