准备之前的操作
1.准备好一个项目文件夹,在文件夹里必须包含着django框架的包,可以直接在pycharm中下载
2.准备好文件之后,在pycharm终端里使用django-admin startproject 项目名(我创建的是tedu_note)
3.在pycharm中open进去用这个命令创建的django框架文件夹
4.进去之后在终端(pyharm的终端我统一叫终端)输入python manage.py runserver启动这个服务
5.打开settings.py 修改最下面的两行代码,分别是语言和时区
代码示例
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'
6.然后修改数据库的一些配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.数据库引擎',
'NAME': '数据库名称',
'USER': '数据库用户名',
'PASSWORD': '数据库密码',
'HOST': '数据库的ip',
'POST': '数据库的端口',
}
}
7.关闭csrf验证
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
8.查看终端的启用的服务是否有报错
用户注册模块
后端
1.先用python manage.py startapp 应用名创建一个应用,我创建的是user
2.每创建一个应用都得在settings下注册一下应用,然后配一下sessions的存储时间
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'user',
]
# sesstion存在时间
SESSION_COOKIE_AGE = 60 * 60 * 24
3.在user应用下的moles.py中创建一个模型类
代码示例
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 '用户' + '%s'%(self.username)
4.执行python manage.py makemigrations 数据库迁移命令 ,然后就是数据库迁移同步python manage.py migrate命令
5.回到views里面去创建一个视图函数,在里面写一些代码的逻辑(因为懒得写,直接在代码中注释一下直接一步到位)
from django.http import HttpResponse,HttpResponseRedirect
from django.shortcuts import render
from user.models import User
import hashlib
#自定义一个视图函数
def reg_view(request):
#GET请求就打开这个user下register.html文件
if request.method == 'GET':
return render(request,'user/register.html')
#发送POST请求处理数据
elif request.method == 'POST':
#获取从前端发送过来的用户名
username = request.POST['username']
#获取从前端发送过来的两个密码
password_1 = request.POST['password_1']
password_2 = request.POST['password_2']
#进行一个判断用户名和密码不能为空的情况
if not username:
return HttpResponse('用户名和密码不能为空')
if not password_1 and not password_2:
return HttpResponse('用户名和密码不能为空')
#判断两段密码是否一致
if password_1 != password_2:
return HttpResponse('密码不一致')
#将哈希算法的md5算法给一个变量封装
m = hashlib.md5()
#将密码用utf-8的编码进行哈希算法进行加密
m.update(password_1.encode())
#将哈希算法用16进制提取
password_m = m.hexdigest()
#把从前端拿到的用户名到数据库进行查询,然后进行判断,如果有就返回一个用户名已注册的页面
old_user = User.objects.filter(username=username)
if old_user:
return HttpResponse('用户名已注册')
#插入数据明文处理密码
#使用判断是否异常的函数进行判断是否异常
try:
#进行插入数据,将获取到的用户名和进行哈希算法加密的密码进行数据库存储
user = User.objects.create(username=username,password=password_m)
except Exception as e:
#有可能 报错 - 重复插入 [唯一索引注意并发写入问题]
print('--create user error is'%(e))
return HttpResponse('用户名已注册')
#免登录一天
#进行一个session会话存储,键值对,方便登录的时候判断假如用户名存在就是已经登录过,一天就不用登录了
request.session['username'] = username
request.session['uid'] = user.id
# user_pass.save()
# return HttpResponse('注册成功')
#后面的首页的url
return HttpResponseRedirect('/index')
6.在和项目同名的文件中打开urls(主路由),在里面配置分布式路由,路由的名字随便配就好了
from django.contrib import admin
from django.urls import path,include
from index import views as index_views
urlpatterns = [
path('admin/', admin.site.urls),
#http://127.0.0.1:8000/user/...
#include是将路由进行一个转发的作用
path('user/' , include('user.urls')),
]
7.在用户所在的文件夹下new一个urls.py,输入如下代码
from django.urls import path
from . import views
urlpatterns = [
#http://127.0.0:8000/user/reg
path('reg' , views.reg_view),
]
前端
1.在user里new一个templates文件夹,在里面再new一个user文件
2.再user/templates/user下new一个html文件register.html
3.进入register.html文件,代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
#将数据提交到这个url,使用post提交
<form action="http://127.0.0.1:8000/user/reg" method="post" >
#创建一个文本框,给他一个名字
用户名: <input type="text" name="username"></br>
#创建一个密码框,给他一个名字
密码: <input type="password" name="password_1"></br>
#创建一个密码框,给他一个名字
再次输入密码: <input type="password" name="password_2"></br>
#提交数据
<input type="submit" value="注册">
</form>
</body>
</html>
浏览器的页面
登录模块
后端
1.因为只是负责进行登录所以直接在views中创建一个视图函数login_view
def login_view(request):
if request.method == 'GET':
# 获取登录页面
# 检查登录状态,如果登录了,就给一个302跳转页面
#判断是否在浏览器上有没有存储的sessions,如果有就302跳转到首页
#首页会在后面进行配置
if request.session.get('username') and request.session.get('uid'):
# return HttpResponse('--已登录')
return HttpResponseRedirect('/index')
#如果sessions没有数据就获取COOIES的数据
c_username = request.COOKIES.get('username')
c_uid = request.COOKIES.get('uid')
#如果两个执行成功就会回写一个session,并进行一个302跳转页面
#假如没有就render一个页面
if c_username and c_uid:
#回写session
request.session['username'] = c_username
request.session['uid'] = c_uid
# return HttpResponse('--已登录')
return HttpResponseRedirect('/index')
return render(request , 'user/login.html')
#判断是否用了post提交数据
elif request.method == 'POST':
#处理数据
#将提交的数据进行一个变量的存储
password = request.POST['password']
username = request.POST['username']
# 查询用户名,异常就进行一个打印,,然后返回一个响应字符串
#因为登录的时候怕用户名和密码会有风险,密码和用户名的错误并不会直接指明
try:
user = User.objects.get(username=username)
# except Exception as e:
except:
print('--login user error is')
return HttpResponse('用户名或密码输入有误')
#调用哈希算法中的md5算法
s = hashlib.md5()
#把进行获取的数据先进行一个utf8编码然后进行一个加密的操作
s.update(password.encode())
#把数据用16进制的方式进行提取
password_w = s.hexdigest()
#判断用户输入的数据和数据库中进行存储的数据相不相同
if password_w != user.password:
return HttpResponse('用户名或密码输入有误')
#记录会话状态
#接着再存储一下用户名,因为能走到这边,必定是之前存储的会话已过期
request.session['username'] = username
request.session['uid'] = user.id
# resp = HttpResponse('--登录成功--')
#将一个响应302跳转赋给一个变量
resp = HttpResponseRedirect('/index')
#判断用户是否 点选了'记住用户名'
#如果点击了就会以一个键值对的形式存储在浏览器,可以自己去浏览器最底下查看
if 'remember' in request.POST:
resp.set_cookie('username' , username , 60*60*60*3)
resp.set_cookie('uid' , user.id , 60*60*60*3)
#点选了 -> Cookies 存储 username,uid
#302跳转
return resp
2.配置路由
from django.urls import path
from . import views
urlpatterns = [
path('login' , views.login_view),
]
前端
1.在templates下的login.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="http://127.0.0.1:8000/user/login" method="post">
用户名: <input type="text" name="username"></br>
密码: <input type="password" name="password"></br>
<input type="checkbox" name="remember">记住用户名</br>
<input type="submit" value="登录">
</form>
</body>
</html>
首页模块
1.在终端下创建一个应用index,并在settings里进行注册
2.因为是首页,我可以不用把路由进行分发,直接把在index的视图进行一个导入即可,因为怕后面名字进行了一些冲突用as起一个别名
from index import views as index_views
urlpatterns = [
path('index' , index_views.index_view),
]
3.进入到index应用下的视图中创建视图函数
from django.shortcuts import render
# Create your views here.
def index_view(request):
#render传页面之后会把请求传过去
return render(request , 'index/index.html')
前端
1.在templates文件下的应用同名文件夹下创建一个index.html文件
2.html骨架中使用模板语法获取session和cookie
3.使用if判断一下,如果有session就走session,没有就走cookie,都没有就需要重新登录或者注册一个
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
{% if request.session.username %}
欢迎{{ request.session.username }}</br>
<a href="/user/logout">退出登录</a></br>
<a href="http://127.0.0.1:8000/note/all">进入我的笔记</a></br>
{% else %}
{% if request.COOKIES.username%}
欢迎{{ request.COOKIES.username }}</br>
<a href="/user/logout">退出登录</a></br>
<a href="http://127.0.0.1:8000/note/all">进入我的笔记</a></br>
{% else %}
<a href="/user/login">登录</a>
<a href="/user/reg">注册</a>
{% endif %}
{% endif %}
</body>
</html>
笔记模块
后端
1.先创建一个应用note,并在settings注册一下
2.在主路由进行url的一个分发
from django.contrib import admin
from django.urls import path,include
from index import views as index_views
urlpatterns = [
path('note/' , include('note.urls')),
]
3.创建一个模型类,并使用用户表数据添加一个外键约束,形成一个一对多的映射
from django.db import models
from user.models import User
# Create your models here.
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)
is_active = models.BooleanField('是否活跃', default=True)
4.在视图中写一个装饰器,以便不用每次都进行获取session和cookie代码如下
#写一个装饰器来判断用户是否登录
def check_login(fn):
def wrap(request , *args , **kesrgs):
#判断用户名和id是否存在session里
if 'username' not in request.session or 'uid' not in request.session:
#如果不在就查询cookie
username_c = request.COOKIES.get('username')
uid_c = request.COOKIES.get('uid')
if not username_c or not uid_c:
#不在就给一个302跳转到登录界面
return HttpResponseRedirect('http://127.0.0.1:8000/user/login')
else:
#如果在cookie在的话就给session存一份
request.session['username'] = username_c
request.session['uid'] = uid_c
return fn(request , *args , **kesrgs)
return wrap
5.然后就可以写笔记本的一个模块
#使用装饰器
@check_login
def list_view(request):
#对数据库进行一个条件查询
note_all = Note.objects.filter(is_active=True)
#返回一个页面和上面变量以字典输出
return render(request , 'note/list_note.html' , locals())
#装饰器查看是否登录
@check_login
#对数据进行一个添加的一个操作
def add_view(request):
#GET请求时就返回一个页面
if request.method == 'GET':
return render(request,'note/add_note.html')
#POST处理数据
elif request.method == 'POST':
#获取sessio的uid和获取表单传过来的title和content
uid = request.session['uid']
title = request.POST['title']
content = request.POST['content']
#对数据进行一个添加,但是不要忘记一个外键也得进行一个添加
Note.objects.create(title=title , content=content,user_id=uid)
# alert = '<script>window.alert(添加笔记成功)</script>'
#一个302跳转页面
return HttpResponseRedirect('http://127.0.0.1:8000/note/all')
@check_login
#对数据进行一个更新操作
def update_view(request,note_id):
#对这个数据进行异常监测
try:
#对Note表进行一个条件查询,note_id是给url当中的一个参数给赋值
note = Note.objects.get(id=note_id, is_active=True)
#数据异常的一个处理
except:
print('--update title error is')
return HttpResponse('--The note is existed')
#GET请求就输出一个页面
if request.method == 'GET':
return render(request , 'note/update_note.html' , locals())
#POST处理数据
elif request.method =='POST':
#获取表单传过来的数据
title = request.POST['title']
content = request.POST['content']
#对数据进行一个条件查询,然后进行重新赋值,并保存
note = Note.objects.get(id=note_id, is_active=True)
note.title = title
note.content = content
note.save()
#302跳转
return HttpResponseRedirect('http://127.0.0.1:8000/note/all')
@check_login
#对数据进行一个伪删除的操作
def delete_view(request):
#从get请求中拿数据
if request.method == 'GET':
note_id = request.GET.get('note_id')
#如果没有就返回失败
if not note_id :
return HttpResponse('---请求失败')
#异常检测
try:
note = Note.objects.get(id=note_id,is_active=True)
#异常输出
except Exception as e:
print('---delete onte get error %s ' % (e))
return HttpResponse('---The note id is error')
#成功拿到就修改值并保存
note.is_active = False
note.save()
#302跳转
return HttpResponseRedirect('http://127.0.0.1:8000/note/all')
@check_login
#对笔记名进行点击之后输出的一个结果
def content_view(request):
#GET请求拿数据
if request.method == 'GET':
note_id = request.GET.get('note_id')
#没拿到就输出请求失败
if not note_id:
return HttpResponse('--请求失败')
#异常检测
try:
note = Note.objects.get(id=note_id , is_active=True)
except Exception as e:
print('--content note get error %s ' % (e))
return HttpResponse('---The note id is error')
#拿到这个数据
content = note.content
#给他一个内容和一个超链接
resp = '''<a href="http://127.0.0.1:8000/note/all">返回笔记</a></br>
</br>
<textarea cols="120" rows="30" disabled="disabled">'''+content+'''</textarea>'''
return HttpResponse(resp)
6.对路由进行一个配置
from django.urls import path
from . import views
urlpatterns = [
#进入笔记呈现的一个url
path('all' , views.list_view),
#对笔记进行添加的一个url
path('add' , views.add_view),
#对数据进行一个更新的一个操作
path('update_note/<int:note_id>' , views.update_view),
#对数据进行一个删除的操作,删除只是一个伪删除
path('delete_note' , views.delete_view),
#一个内容的一个超链接
path('content' , views.content_view),
]
前端
1.创建三个html文件list_note,add_note,update_note
2.在list_note装一个进入笔记的一个首页,里面的超链接就不细讲了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>笔记</title>
</head>
<body>
<div>
<span>tedu笔记</span>
<a href="http://127.0.0.1:8000/note/add">添加新笔记</a>
<a href="http://127.0.0.1:8000/index">返回首页</a>
</div>
<p></p>
<table border="1">
<tr>
<th>ID</th>
<th>标题</th>
<th>创建时间</th>
<th>修改时间</th>
<th>
<span>修改</span> <span>删除</span>
</th>
</tr>
{% for note in note_all %}
<tr>
<td>{{ note.id }}</td>
<td><a href="/note/content?note_id={{ note.id }}">{{ note.title }}</a></td>
<td>{{ note.created_time }}</td>
<td>{{ note.updated_time }}</td>
<td>
<!-- note.id是在请求的时候一个传参-->
<a href="/note/update_note/{{ note.id }}">修改</a>
<a href="/note/delete_note?note_id={{ note.id }}">删除</a>
</td>
</tr>
{%endfor%}
</table>
</body>
</html>
3.add_note装一个添加笔记的一个页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加笔记</title>
</head>
<body>
<form method="post" action="http://127.0.0.1:8000/note/add">
主题 <input type="text" name="title">
<input type="submit" value="保存">
<a href="http://127.0.0.1:8000/note/all"></a></br>
<textarea cols="50" rows="30" name="content"></textarea>
</form>
</body>
</html>
4.update_note更新的一个操作,有些就不需要html文件,直接给他成功之后一个302跳转回来就行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>修改</title>
</head>
<body>
<form method="post" action="http://127.0.0.1:8000/note/add">
主题 <input type="text" name="title">
<input type="submit" value="保存">
<a href="http://127.0.0.1:8000/note/all"></a></br>
<textarea cols="50" rows="30" name="content"></textarea>
</form>
</body>
</html>