云笔记项目

文章目录

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

一般项目组成成员

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

功能拆解

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

  • 用户模块

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

初始化项目

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

django-admin startproject tedu_note
  • 禁止csrf

  • 语言更改
  • 时区更改
  • 数据库配置
  • 创建/注册应用 user

用户模型类设计

创建我们的 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
  • 界面样式
  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>Document</title>
</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>

  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, includeurlpatterns = [path('admin/', admin.site.urls),path('user/',include("user.urls"))
]
# 子 urls.py 内容
from django.urls import path
from . import viewsurlpatterns = [path('reg', views.reg_view)
]
  1. 查看我们的页面

用户注册 第二版

我们现在新增了 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("注册成功!")

要求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 注册免登录一天

# 免登陆一天
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
#mermaid-svg-pt44VKc9E1RrvXZj {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-pt44VKc9E1RrvXZj .error-icon{fill:#552222;}#mermaid-svg-pt44VKc9E1RrvXZj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pt44VKc9E1RrvXZj .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-pt44VKc9E1RrvXZj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pt44VKc9E1RrvXZj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pt44VKc9E1RrvXZj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pt44VKc9E1RrvXZj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pt44VKc9E1RrvXZj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pt44VKc9E1RrvXZj .marker.cross{stroke:#333333;}#mermaid-svg-pt44VKc9E1RrvXZj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pt44VKc9E1RrvXZj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-pt44VKc9E1RrvXZj .cluster-label text{fill:#333;}#mermaid-svg-pt44VKc9E1RrvXZj .cluster-label span{color:#333;}#mermaid-svg-pt44VKc9E1RrvXZj .label text,#mermaid-svg-pt44VKc9E1RrvXZj span{fill:#333;color:#333;}#mermaid-svg-pt44VKc9E1RrvXZj .node rect,#mermaid-svg-pt44VKc9E1RrvXZj .node circle,#mermaid-svg-pt44VKc9E1RrvXZj .node ellipse,#mermaid-svg-pt44VKc9E1RrvXZj .node polygon,#mermaid-svg-pt44VKc9E1RrvXZj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pt44VKc9E1RrvXZj .node .label{text-align:center;}#mermaid-svg-pt44VKc9E1RrvXZj .node.clickable{cursor:pointer;}#mermaid-svg-pt44VKc9E1RrvXZj .arrowheadPath{fill:#333333;}#mermaid-svg-pt44VKc9E1RrvXZj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pt44VKc9E1RrvXZj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pt44VKc9E1RrvXZj .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-pt44VKc9E1RrvXZj .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-pt44VKc9E1RrvXZj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pt44VKc9E1RrvXZj .cluster text{fill:#333;}#mermaid-svg-pt44VKc9E1RrvXZj .cluster span{color:#333;}#mermaid-svg-pt44VKc9E1RrvXZj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pt44VKc9E1RrvXZj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

GET请求
POST请求
当前是POST请求
当前是GET请求
用户勾选记住我
用户没有勾选记住我
有session
没有session
有cookies
没有cookies
检查数据库是否有session
检查是否有Cookie
重新存入session到服务器
返回登录页面
向数据库存入session
执行正常登陆流程
用户是否勾选了记住我
向浏览器存入cookies
主页
用户进入登陆页面
判断当前是POST还是GET

用户登陆

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

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

退出登陆

  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. 查看网页

笔记模型类

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)

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

015 Django 云笔记项目(可以略过)相关推荐

  1. Django——云笔记项目2

    在上一讲的基础上,进行用户模型类设计 1 用户模型类设计 1.1 编写 models.py 文件 models.py 文件中的一个类对应数据库中的一张表,类中的属性对应表中的字段,利用 Django ...

  2. Django小项目:云笔记项目

    云笔记项目 云笔记项目 项目准备 shell操作 settings.py 用户注册模块 用户登录模块 网站首页 笔记模型模块 列表页 注册后台 项目部署 云笔记项目 云笔记项目 - 功能拆解 用户模块 ...

  3. Django(part52)--项目部署

    学习笔记,仅供参考 文章目录 项目部署 项目部署的几个步骤 安装同版本的数据库(略) django项目迁移 安装python 安装相同版本的包 将当前项目源代码复制到运程主机上(scp 命令) ssh ...

  4. Django blog项目《二十五》:项目优化《1》使用celery异步任务和定时任务

    celery异步异步任务处理 一.celery简介 celery 官方文档英文版:http://docs.celeryproject.org/en/latest/index.html 组件 任务Tas ...

  5. Django Python:完整的BUNDLE + Django真实项目2021

    Django和python Bundle:从学习python的所有基础知识到高级python再到UI设计TKINTER,然后是Django 你会学到: 学习编程的基础知识 学习Python编程语言 学 ...

  6. django创建项目,创建app以及调用templates(模版)和static(静态文件)的方法

    # django创建项目,创建app以及调用templates和static的方法 创建项目project 检查django的版本.我用的是2.2.1版本 打开终端,输入命令: python -m d ...

  7. 云笔记项目-补充JS面向对象编程基础知识

    简单介绍: 此部分知识为在做云笔记项目中补充,因为云笔记项目中涉及到前端js,里面写了很多js脚本,用到了创建js属性和方法,在js中直接声明的属性和方法最终都会变成window的对象,即其成为了全局 ...

  8. 云笔记项目-过滤器与拦截器学习

    在做云笔记项目的过程中,没有登录的情况下,也可以直接访问edit.html页面.这个跟以前自己用Servlet做过的PadAndFilterManagement情况类似,当时在没有登录的情况下可以访问 ...

  9. Django创建项目后,项目文件夹下的组成部分

    Django创建项目后,项目文件夹下的组成部分 项目文件夹下的组成部分: manage.py 是项目运行的入口,指定配置文件路径.与项目同名的目录,包含项目的配置文件.   init.py 是一个空文 ...

最新文章

  1. 剑指offer_第8题_跳台阶
  2. SpringCloud OpenFeign 远程HTTP服务调用用法与原理
  3. python学习笔记(一)基本数据类型
  4. 黑客必须了解的网络知识
  5. 一个java 验证码的实现提供多种的实现
  6. ArrayList、Vector、LinkedList的特点和区别
  7. java children_java构建树形列表(带children属性)
  8. 关于 C# 请求 https 那点事
  9. Mac上的全局翻译利器 : Bob + PopClip
  10. breadweb控制台下载_路由器刷breed助手下载
  11. 教你如何破解无线网络密码(无线网络密码破解)
  12. 根据身份证号 计算具体年龄
  13. TSO/GSO/LRO/GRO
  14. 读书感受 之 《写给年轻人的 经济学故事书》
  15. 详解OpenWrt路由器设置Crontab定时检查网络并重启
  16. 随机向量函数链神经网络(RVFLNN)
  17. 每日刷题之数独简单版 AcWing 1613
  18. Android 5.0系统特性全解析
  19. bag of tricks for image classification with convolutional neural networks
  20. 软件可靠性工程研讨会报告

热门文章

  1. TDengine:开源、高效的物联网大数据平台
  2. 龙蜥LoongArch架构研发全揭秘,龙芯开辟龙腾计划技术合作新范式
  3. 【WiFi】hostapd 配置80M频宽某些信道启动失败问题分析及解决
  4. python怎么读是啥意思-python怎么读?python的含义和读音!
  5. 麦兜与春田花花幼稚园
  6. WebService 理论详解、JWS(Java Web Service) 快速入门
  7. day21|216.组合总和III、17.电话号码的字母组合
  8. 使用腾讯云Ubuntu20.04搭建代理服务器
  9. 源码时代软测干货分享|带你了解CGI支持模块
  10. 新手必看--test link使用步骤