pt27网络云笔记项目

网络云笔记项目

七项功能: 注册、登陆、退出登陆、查看笔记列表、创建新笔记、修改笔记、删除笔记

数据库设计

模型类

user-app模型类 —>> 注册、登陆、退出登陆

note-app用户模型类 —>> 查看笔记列表、创建新笔记、修改笔记、删除笔记

初始化配置

[root@vm ~]# mysql -uroot -p123456 -e 'create database net_note default charset utf8;'

[root@vm ~]# django-admin startproject net_note
[root@vm ~]# cd net_note
[root@vm net_note]# python3 manage.py startapp user
[root@vm net_note]# python3 manage.py startapp note

[root@vm net_note]# ls
manage.py  net_note

[root@vm net_note]# vim net_note/settings.py

ALLOWED_HOSTS = ['*',]
INSTALLED_APPS = [
...
    'user',
    'note',
    
MIDDLEWARE = [
...
#先注释了,问题暂不解决  'django.middleware.csrf.CsrfViewMiddleware',


DATABASES = {
    'default' : {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'net_note',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = "Asia/Shanghai"

[root@vm net_note]# python3 manage.py runserver 0.0.0.0:8000

user

[root@vm net_note]# vim user/models.py
from django.db import models
class User(models.Model):
    username = models.CharField("用户名", max_length=30, unique=True)
    password = models.CharField("密码", max_length=32)
    created_time = models.DateTimeField('创建时间', auto_now_add=True)
    updated_time = models.DateTimeField('更新时间', auto_now=True)

    def __str__(self):
        return "用户" + self.username

note

[root@vm net_note]# vim note/models.py
from django.db import models
from user.models import User

class Note(models.Model):
    title = models.CharField('标题', max_length=100)
    content = models.TextField('内容')
    created_time = models.DateTimeField('创建时间', auto_now_add=True)
    updated_time = models.DateTimeField('更新时间', auto_now=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
[root@vm net_note]# python3 manage.py makemigrations
Migrations for 'user':
  user/migrations/0001_initial.py
    - Create model User
Migrations for 'note':
  note/migrations/0001_initial.py
    - Create model Note
[root@vm net_note]# python3 manage.py migrate  
[root@vm net_note]# mysql -uroot -p123456 -e 'use net_note;show tables;'
+----------------------------+
| note_note                  |
| user_user                  |
+----------------------------+  #查看数据库验证app名_model类名的表

user设计规范

先配置号路由,再考虑界面功能

路由正则 视图函数 模板位置 说明
/user/login login_view templates/user/login.html 登陆
/user/reg reg_view templates/user/register.html 注册
/user/logout logout_view 退出

user总路由

[root@vm net_note]# vim net_note/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
...
    path('user/',include('user.urls')),

user-注册

子路由

[root@vm net_note]# vim user/urls.py
from django.urls import path
from . import views
urlpatterns =[
   path('reg',views.reg_view),
]

初步设计注册函数

[root@vm net_note]# vim user/views.py
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse, HttpResponseRedirect

# Create your views here.
def reg_view(request):
    if request.method == 'GET':
        return render(request, 'user/register.html')
    elif request.method == 'POST':
        return HttpResponse('注册成功!')

初步创建注册页面

[root@vm net_note]# mkdir -p user/templates/user
[root@vm net_note]# vim user/templates/user/register.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
</head>
<body>
</body>
</html>

初步验证

http://192.168.1.11:8000/user/reg      #title显示 用户注册

完善注册页面

[root@vm net_note]# vim user/templates/user/register.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
</head>
<body>
<form action="/user/reg" method="post">
    <p>
        用户名:<input type="text" name="username">
    </p>
    <p>
        密码:<input type="password" name="password_1">
    </p>
    <p>
        再次密码:<input type="password" name="password_2">
    </p>
    <p>
        <input type="submit" value="注册">
    </p>

</form>
</body>
</html>

初步验证前后端逻辑

http://192.168.1.11:8000/user/reg      #点击注册,显示注册成功

完善注册函数

常见的hash算法MD5 SHA1 SHA256, hash值不可逆运算,一般将密码hash,存hash值,(密码+时间戳hash安全些),MD5 128位,32个字符,字段长度32。 sha256 256位,字段长度64

网上的破解都是算好的值,比如123456的值,查hash值得出123456。并不能逆运算得出

>>> import hashlib
>>> passwd='123456'
>>> md5=hashlib.md5()
>>> md5.update(passwd.encode())  #转换成字节串
>>> md5.hexdigest()      #转换成16进制
'e10adc3949ba59abbe56e057f20f883e'
# sha256
>>> sha=hashlib.sha256()
>>> sha.update(passwd.encode())
>>> sha.hexdigest()
'8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92'
1、hash算法计算结果定长输出,无论原始数据的大小
2、不可逆,根据hash值无法通过算法再计算出原始数据
3、输入敏感(雪崩效应),原始数据的微小修改都会造成hash值完全不同
>>> passwd2='123455'
>>> sha.update(passwd2.encode())
>>> sha.hexdigest()
'd5b1a767a48ed624e6b6ab70fe39f34539b3b40fe6900a6369f0b0e1ef0af827'

[root@vm net_note]# vim user/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
import hashlib
from .models import User

# Create your views here.
def reg_view(request):
    if request.method == 'GET':
        return render(request, 'user/register.html')
    elif request.method == 'POST':
        # 1.接收用户提交的数据  根据form表单的name值去拿,打印验证
        username = request.POST['username']
        password_1 = request.POST['password_1']
        password_2 = request.POST['password_2']
        # print(username, password_1, password_2)
        # 2.数据检查,验证为空返回
        if not username or not password_1:
            return HttpResponse("用户名和密码都不能为空")
        if password_1 != password_2:
            return HttpResponse("两次密码要一致")
        # 3.计算密码的hash值
        md5 = hashlib.md5()
        md5.update(password_1.encode())
        password_h = md5.hexdigest()
        # 4.将数据添加到数据库
        try:
            User.objects.create(username=username,
                                password=password_h)
        except:
            return HttpResponse("用户名称被占用")

        return HttpResponse('注册成功!')

注册验证,重名尝试,数据库查看

user-登录

子路由

[root@vm net_note]# vim user/urls.py
from django.urls import path
from . import views
urlpatterns =[
   path('reg',views.reg_view),
   path('login',views.login_view),
]

初步设计登录函数

[root@vm net_note]# vim user/views.py
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse, HttpResponseRedirect

# Create your views here.
def login_view(request):
    if request.method == "GET":
        return render(request, 'user/login.html')
    elif request.method == "POST":
        return HttpResponse("登录成功!")

初步创建登录页面

[root@vm net_note]# vim user/templates/user/login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>
</body>
</html>

初步验证

http://192.168.1.11:8000/user/login     #title显示 用户登录

完善注册页面

[root@vm net_note]# vim user/templates/user/login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
</head>
<body>
<form action="/user/login" method="post">
    <p>
        用户名:<input type="text" name="username">
    </p>
    <p>
        密码:<input type="text" name="password">
    </p>
    <p>
        <input type="submit" value="登录">
    </p>
</form>
</body>
</html>

初步验证前后端逻辑

http://192.168.1.11:8000/user/login      #点击登录,显示登录成功

完善注册函数

[root@vm net_note]# vim user/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
import hashlib
from .models import User

# Create your views here.
def login_view(request):
    if 'username' in request.session and 'uid' in request.session:
        # 以后可以重定向到笔记列表
        return HttpResponse("您已经登录了")

    if request.method == "GET":
        return render(request, 'user/login.html')
    elif request.method == "POST":
        # 登录逻辑
        # 1 获取用户输入的数据
        username = request.POST['username']
        password = request.POST['password']
        # 2 为空判断
        if not username or not password:
            return HttpResponse("用户名和密码都不能为空")
        # 3 根据用户名获取用户对象
        try:
            user = User.objects.get(username=username)
        except:
            return HttpResponse("用户名或密码错误")
        # 4 计算密码的hash值
        md5 = hashlib.md5()
        md5.update(password.encode())
        password_h = md5.hexdigest()
        if password_h != user.password:
            return HttpResponse("用户名或密码错误")
        # 5 在session中保存用户数据
        request.session['username'] = user.username
        request.session['uid'] = user.id
        # return HttpResponse("登录成功!")
        return HttpResponseRedirect("/note/")

登录验证,重名尝试,数据库查看

[root@vm net_note]# mysql -uroot -p123456 -e 'select * from net_note.django_session;'
Empty set (0.00 sec)

http://192.168.1.11:8000/user/login  #登录验证

[root@vm net_note]#  mysql -uroot -p123456 -e 'select * from net_note.django_session\G'
*************************** 1. row ***************************
 session_key: 8w85iwmmzvd78qj82h645h8licl3ruzf
session_data: NDlkN2Y0OTE5NGQ0ZTM3MWNiODkzNDkwZm...

浏览器查看cookies里的sessionid :8w85iwmmzvd78qj82h645h8licl3ruzf

user-退出

子路由

[root@vm net_note]# vim user/urls.py
from django.urls import path
from . import views
urlpatterns =[
   path('reg',views.reg_view),
   path('login',views.login_view),
   path('logout',views.logout_view),
]

设计退出函数

[root@vm net_note]# vim user/views.py
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse, HttpResponseRedirect

# Create your views here.
def logout_view(request):
    if 'username' in request.session:
        del request.session['username']
    if 'uid' in request.session:
        del request.session['uid']
    return HttpResponse("用户注销成功!")

退出验证

http://192.168.1.11:8000/user/logout

note设计规范

路由正则 视图函数 模板位置 说明
/note/ list_view templates/note/list_note.html 显示笔记列表功能
/note/add add_view templates/note/add_note.html 添加云笔记
/note/mod/(\d+) mod_view templates/note/mod_note.html 修改之前云笔记
/note/del/(\d+) del_view 无(返回列表页) 删除云笔记

note总路由

[root@vm net_note]# vim net_note/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
...
    path('note/',include('note.urls')),   

显示、添加功能子路由

[root@vm net_note]# vim note/urls.py
from django.urls import path
from . import views
urlpatterns =[
    path('', views.list_view),
    path('add', views.add_view),    
]

初步设计函数

[root@vm net_note]# vim note/views.py
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse, HttpResponseRedirect

def list_view(request):
    # 读取笔记,locals()传递数据
    return render(request,
                  'note/list_note.html',
                  locals())
                  
def add_view(request):
    if request.method == 'GET':
        return render(request,
                      'note/add_note.html')
    elif request.method == 'POST':
        # add your code here
        return HttpResponse("添加笔记成功!")                  

初步创建页面

[root@vm net_note]# mkdir -p note/templates/note
[root@vm net_note]# vim note/templates/note/list_note.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>笔记列表</title>
</head>
<body>
</body>
</html>

[root@vm net_note]# vim note/templates/note/add_note.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加笔记</title>
</head>
<body>
<a href="/note/">返回列表页</a>
<form action="/note/add" method="post">
    <p>
        标题:<input type="text" name="title">
        <input type="submit" value="提交">
    </p>
    <textarea name="content" cols="40" rows="10">

    </textarea>
</form>
</body>
</html>

初步验证

http://192.168.1.11:8000/note/     #title显示 笔记列表
http://192.168.1.11:8000/note/add    #返回列表页

装饰器使用

从功能设计上,对笔记的增删改查的操作,操作前,都需要做登录认证。可以编写登录认证的装饰器。

[root@vm net_note]# vim note/views.py
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponse, HttpResponseRedirect
#装饰器函数
def login_check(fn):
    def wrap(request, *args, **kwargs):
        if 'username' not in request.session or 'uid' not in request.session:
            # 需要重定向到登录页面
            return HttpResponseRedirect('/user/login')
        else:
            #返回修饰调用的函数
            return fn(request, *args, **kwargs)
    return wrap

def list_view(request): ...
    
@login_check
def add_view(request): ....

初步验证装饰器

#先删掉cookie
访问http://192.168.1.11:8000/note/add   跳转到login页面,登录后再次访问不跳转

完善添加功能函数

[root@vm net_note]# vim note/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render

from .models import Note


# Create your views here.

def login_check(fn):
    def wrap(request, *args, **kwargs):
        if 'username' not in request.session or 'uid' not in request.session:
            # 需要重定向到登录页面
            return HttpResponseRedirect('/user/login')
        else:
            return fn(request, *args, **kwargs)

    return wrap


@login_check
def list_view(request):
    # 读取笔记
    return render(request,
                  'note/list_note.html',
                  locals())


@login_check
def add_view(request):
    if request.method == 'GET':
        return render(request,
                      'note/add_note.html')
    elif request.method == 'POST':
        # 1.从前端提供的表单中获取标题和内容
        title = request.POST['title']
        content = request.POST['content']
        # 2.从session中获取用户ID
        uid = request.session['uid']
        # 3.添加笔记
        Note.objects.create(title=title,
                            content=content,
                            user_id=uid)

        return HttpResponse("添加笔记成功!")

随便添加一条笔记验证

[root@vm net_note]# mysql -uroot -p123456 -e 'select * from net_note.note_note\G'
*************************** 1. row ***************************
          id: 1
       title: test
     content: 123

完善显示功能函数

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render

from .models import Note

...
@login_check
def list_view(request):
    # 读取笔记
    # 1. 从session中获取用户名称
    username = request.session['username']
    # 2. 获取该用户的所有笔记
    uid = request.session['uid']
    notes = Note.objects.filter(user_id=uid)
    return render(request,
                  'note/list_note.html',
                  locals())


完善显示页面

user的笔记 添加新笔记
ID 标题 创建时间 修改时间 操作
1 test …09:54 …09:54 修改 删除

[root@vm net_note]# vim note/templates/note/list_note.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>笔记列表</title>
</head>
<body>
{{ username }}的笔记 <a href="/note/add">添加新笔记</a>
<table>
    <tr>
        <th>ID</th>
        <th>标题</th>
        <th>创建时间</th>
        <th>修改时间</th>
        <th>操作</th>
    </tr>
    {% for note in notes %}
    <tr>
        <td>{{ note.id }}</td>
        <td>{{ note.title }}</td>
        <td>{{ note.created_time }}</td>
        <td>{{ note.updated_time }}</td>
        <td>
            <a href="/note/mod/{{ note.id }}">修改</a>
            <a href="/note/del/{{ note.id }}">删除</a>
        </td>
    </tr>
    {% endfor %}
</table>
</body>
</html>

验证功能

http://192.168.1.11:8000/note/   #显示笔记列表,
#点击修改、删除能调到对应的id地址   http://192.168.1.11:8000/note/mod/1

修改、删除功能子路由

[root@vm net_note]# vim note/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.list_view),
    path('add', views.add_view),
    path('mod/', views.mod_view),
    path('del/', views.del_view),
]

初步设计mod、del函数

[root@vm net_note]# vim note/views.py
...
@login_check
def mod_view(request, nid):
    # 根据笔记id,获取笔记对象    1查,待补充
    if request.method == "GET":
        return render(request,
                      'note/mod_note.html',
                      locals())
    elif request.method == "POST":
        # 2改3保存,待补充
        return HttpResponse("修改笔记成功!")

@login_check
def del_view(request, nid):
    # add your code here
    return HttpResponse("添加笔记成功!")

初步设计mod页面

[root@vm net_note]# vim note/templates/note/mod_note.html



    
    <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>修改笔记


返回列表页

标题:

初步验证功能

http://192.168.1.11:8000/note/   #登录后首页,点修改,删除显示OK

完善函数

[root@vm net_note]# vim note/views.py
...
@login_check
def mod_view(request, nid):
    # 根据笔记id,获取笔记对象1查
    uid = request.session['uid']
    try:
        note = Note.objects.get(id=nid,
                                user_id=uid)
    except:
        return HttpResponse("笔记的id有误!")
    if request.method == "GET":
        return render(request,
                      'note/mod_note.html',
                      locals())
    elif request.method == "POST":
        # 2改3保存
        title = request.POST['title']
        content = request.POST['content']
        note.title = title
        note.content = content
        note.save()
        # return HttpResponse("修改笔记成功!")
        # 重定向到笔记列表
        return HttpResponseRedirect("/note/")


@login_check
def del_view(request, nid):
    # add your code here
    uid = request.session['uid']
    try:
        note = Note.objects.get(id=nid,
                                user_id=uid)
        note.delete()
    except:
        return HttpResponse("笔记id有误!")
    return HttpResponse("删除笔记成功")

功能验证

http://192.168.1.11:8000/note/   #点击修改,能返回title跟内容,修改能提交
[root@vm net_note]# mysql -uroot -p123456 -e 'select * from net_note.note_note\G'
*************************** 1. row ***************************
          id: 1
       title: test
     content: 456   #内容有改变
#可以删除,新加,更换用户,显示的都是各自id的笔记

项目总结

用户注册时,密码的处理。【hash算法】
登录/注销。会话状态的存储。【session技术】
笔记模块掌握装饰器的使用,登录认证的装饰器【装饰器】

你可能感兴趣的:(网络,笔记,python)