云笔记项目
- 云笔记项目
- 项目准备
- shell操作
- settings.py
- 用户注册模块
- 用户登录模块
- 网站首页
- 笔记模型模块
- 列表页
- 注册后台
- 项目部署
云笔记项目
云笔记项目 - 功能拆解
用户模块:注册、登陆、退出登陆
笔记模块:增删该查
项目准备
shell操作
创建项目文件夹
django-admin startproject tedu_note
创建用户模块
python manage.py startapp user
创建对应的数据库
mysql> create database tedu_note default charset utf8;
测试是否成功
python manage.py runserver
settings.py
禁用csrf中间件(一个防范csrf攻击的组件)
# setting.py
MIDDLEWARE = [
...
# 'django.middleware.csrf.CsrfViewMiddleware',
...
]
配置数据库
DATABASES = {
'default': {
'ENGINE': 'mysql',
'NAME': 'tedu_note',
'USER': 'root',
'PASSWORD': '2226958871',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
更改时区和地域
# 中文
LANGUAGE_CODE = 'zh-Hans'
# 亚洲/上海
TIME_ZONE = 'Asia/Shanghai'
用户注册模块
先写好数据库的表单
# user/models.py
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)
# 创建时间属性
created_time = models.DateTimeField("创建时间", auto_now_add=True)
# 更新时间
updated_time = models.DateTimeField("更新时间", auto_now=True)
def __str__(self):
return "username %s" % self.username
生成迁移文件
python manage.py makemigrations
# user/migrations/*.py
# Generated by Django 2.2.12 on 2021-07-14 06:31
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='User',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('username', models.CharField(max_length=30, unique=True, verbose_name='用户名')),
('password', models.CharField(max_length=32, verbose_name='密码')),
('created_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
('updated_time', models.DateTimeField(auto_now=True, verbose_name='更新时间')),
],
),
]
数据迁移到数据库
python manage.py migrate
// mysql
show databases;
use tedu_note;
desc user_user;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| username | varchar(30) | NO | UNI | NULL | |
| password | varchar(32) | NO | | NULL | |
| created_time | datetime(6) | NO | | NULL | |
| updated_time | datetime(6) | NO | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)
现在来开始第一个路由:用户注册。此处采用分布式路由方法
首先打开template的APP许可
# settings.py
TEMPLATES = [
...
'APP_DIRS': True,
...
]
然后先在urls进行配置,并重user文件夹中新建urls.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'))
]
接下来是在user文件夹进行配置
cd user
mkdir templates
cd ./templates
mkdir user
接下来写东西
# user/views.py
from django.shortcuts import render
from django.http import HttpResponse
from .models import User
# Create your views here.
def reg_view(request):
# 注册
if request.method == 'GET':
# GET 返回页面
return render(request, 'user/register.html')
elif request.method == 'POST':
# POST 处理提交数据
username = request.POST['username']
password_1 = request.POST['password_1']
password_2 = request.POST['password_2']
# 1 两个密码要保持一致
if password_1 != password_2:
return HttpResponse("两次密码输入不一致")
# 2 当前用户名是否可用
old_user = User.objects.filter(username=username)
if old_user:
return HttpResponse("用户名已经被注册")
# 3 插入数据
User.objects.create(username=username, password=password_1)
return HttpResponse("注册成功")
我们可以加固一下密码:用哈希算法
m = hashlib.md5()
m.update(password_1.encode())
password_m = m.hexdigest()
我们可以来看看数据库的内容
mysql> select * from user_user;
+----+----------+----------------------------------+----------------------------+----------------------------+
| id | username | password | created_time | updated_time |
+----+----------+----------------------------------+----------------------------+----------------------------+
| 1 | lh | e10adc3949ba59abbe56e057f20f883e | 2021-07-14 07:32:34.103765 | 2021-07-14 07:32:34.103765 |
+----+----------+----------------------------------+----------------------------+----------------------------+
2 rows in set (0.00 sec)
免登陆一天
# 免登陆一天
request.session['username'] = username
request.session['id'] = user.id
# settings.py
SESSION_COOKIE_AGE = 60 * 10 * 6 * 24# 设置过期时间10分钟,默认为两周
SESSION_SAVE_EVERY_REQUEST = True
SESSION_EXPIRE_AT_BROWSER_CLOSE = True # 设置关闭浏览器时失效
用户登录模块
配置路由
urlpatterns = [
path('login', views.login_view)
]
def login_view(request):
if request.method == 'GET':
# 获取登陆页面
return render(request, "user/login.html")
elif request.method == 'POST':
# 处理数据
username = request.POST['username']
password = request.POST['password']
try:
user = User.objects.get(username=username)
except Exception as e:
print('--login user error %s' % e)
return HttpResponse('登陆失败')
# 比对密码
m = hashlib.md5()
m.update(password.encode())
if m.hexdigest() != user.password:
return HttpResponse('登陆失败')
# 免登陆一天
request.session['username'] = username
request.session['id'] = user.id
return HttpResponse("登陆成功 ")
下面是优化的免登陆的版本
def login_view(request):
if request.method == 'GET':
# 获取登陆页面
if request.session.get('username') and request.session.get('uid'):
return HttpResponse("已经登陆")
# 检查cookies
c_username = request.COOKIES.get('username')
c_uid = request.COOKIES.get('uid')
if c_username and c_uid:
# 回写session
request.session['username'] = c_username
request.session['uid'] = c_uid
return HttpResponse("已经登陆")
return render(request, "user/login.html")
elif request.method == 'POST':
# 处理数据
username = request.POST['username']
password = request.POST['password']
try:
user = User.objects.get(username=username)
except Exception as e:
print('--login user error %s' % e)
return HttpResponse('登陆失败')
# 比对密码
m = hashlib.md5()
m.update(password.encode())
if m.hexdigest() != user.password:
return HttpResponse('登陆失败')
# 免登陆一天
request.session['username'] = username
request.session['id'] = user.id
resp = HttpResponse("登陆成功 ")
if 'remember' in request.POST:
resp.set_cookie('username', username, 3600 * 24 * 3)
resp.set_cookie('uid', user.id, 3600 * 24 * 3)
return resp
网站首页
用分布式方法生成独立应用模块
python manage.py startapp index
# settings.py
INSTALLED_APPS = [
...
'index',
]
# index/index_view
from django.shortcuts import render
# Create your views here.
def index_view(request):
return render(request, 'index/index.html')
<!--index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
{% if request.session.username %}
<p>
欢迎 {{ request.session.username }}
</p>
<p>
<a href="/user/logout">退出</a>
</p>
<p>
<a href="">进入我的笔记</a>
</p>
{% else %}
{% if request.COOKIES.username %}
<p>
欢迎 {{ request.COOKIES.username }}
</p>
<p>
<a href="/user/logout">退出</a>
</p>
<p>
<a href="">进入我的笔记</a>
</p>
{% else %}
<p>
<a href="/user/login">登陆</a>
</p>
<p>
<a href="/user/reg">注册</a>
</p>
{% endif %}
{% endif %}
</body>
</html>
写一写退出登陆模块
# user/logout
def logout_view(request):
request.session.flush()
response = HttpResponseRedirect('/index')
response.delete_cookie('username')
response.delete_cookie('uid')
return response
笔记模型模块
分布式构建笔记应用
python manage.py startapp note
数据迁移
python manage.py makemigrations
python manage.py migrate
进入数据库里面看看
mysql> desc note_note;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| title | varchar(100) | NO | | NULL | |
| content | longtext | NO | | NULL | |
| created_time | datetime(6) | NO | | NULL | |
| updated_time | datetime(6) | NO | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
5 rows in set (0.01 sec)
配置好路由
urlpatterns = [
path('admin/', admin.site.urls),
path('user/', include('user.urls')),
path('index/', include('index.urls')),
path('note/', include('note.urls'))
]
列表页
from django.urls import path
from . import views
urlpatterns = [
path('all', views.list_view),
path('add', views.add_view),
]
定义视图函数
import requests
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from .models import Note
# Create your views here.
def check_login(fn):
def wrap(request, *args, **kwargs):
if 'username' not in request.session or 'uid' not in request.session:
# 检查cookies
c_username = request.COOKIES.get('username')
c_uid = request.COOKIES.get('uid')
if not c_username or not c_uid:
return HttpResponseRedirect('/user/login')
else:
# 回写session
request.session['username'] = c_username
request.session['uid'] = c_uid
return fn(request, *args, **kwargs)
return wrap
def list_view(request):
pass
@check_login
def add_view(request):
if request.method == 'GET':
return render(request, 'note/add_note.html')
elif request.method == 'POST':
# 处理数据
uid = request.session['uid']
title = request.POST['title']
content = request.POST['content']
Note.objects.create(title=title, content=content)
return HttpResponse("添加笔记成功")
注册后台
python manage.py createsuperuser
把数据放入后台
from django.contrib import admin
from .models import 模型类
# Register your models here.
admin.site.register(模型类)
项目部署
我这个是Windows下的,所以得先把项目放置到服务器上(ssh连接)
? ~ cd ./Pycharm
? Pycharm ls
db.sqlite3 index manage.py mysql note tedu_note user
安装相关的库
sudo pip3 install uwsgi
sudo apt-get install libmysqlclient-dev
pip install mysqlclient
启动uwsgi
uwsgi --ini uwsgi.ini
[uWSGI] getting INI configuration from uwsgi.ini