Django 批量迁移数据 分页类 cookie session
批量迁移数据
单纯使用for循环添加,这样数据量过大速度会很慢。
from app01 import models
l=[]
for i in range(10000):
book_obj = models.Book(title='老人与海%s'%i)
l.append(book_obj)
models.Book.objects.bulk_create(l)
# 当需要批量添加数据的时候,bulk_create可以很快的添加的数据
# 相当于只执行一次sql语句
models.Book.objects.count() # 可以数数据
分页类的使用
views.py
def home(request):
current_page = request.GET.get('page', 1) # 当前页应该从前端获取
try:
current_page = int(current_page)
except:
current_page = 1
per_page = 10 # 每页显示的条数是固定的
'''
per_page = 10
current_page start_page end_page
1 0 10
2 10 20
3 20 30
'''
page_start = (current_page - 1) * per_page
page_end = current_page * per_page
book_list = models.Book.objects.all()[page_start:page_end] # 切片
# 计算出总页数
all_count = models.Book.objects.all().count()
all_page, remainder = divmod(all_count, 10)
# 如果有余数页数加1
if remainder:
all_page += 1
# 将分页标签循环 再传到html页面
html = ''
for i in range(1, all_page):
html += '<li><a href="?page=%s">%s</a></li>' % (i, i)
return render(request, 'home.html', locals())
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>home</title>
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'CSS/bootstrap.css' %}"/>
<script src="{% static 'JS/bootstrap.min.js' %}"></script>
<script src="{% static 'jQuery/jquery-3.6.0.min.js' %}"></script>
</head>
<body>
<table class="table-striped table text-center">
<thead>
<tr>
<th class="text-center">id</th>
<th class="text-center">书名</th>
</tr>
</thead>
<tbody>
{% for book in book_list %}
<tr>
<td>{{ book.id }}</td>
<td>{{ book.title }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{{ html|safe }}
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</body>
</html>
分页类的使用
这是个类需要在Django根目录创建一个文件夹添加py文件,将它复制到py文件中导入使用。
class Pagination(object):
def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
"""
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page < 1:
current_page = 1
self.current_page = current_page
self.all_count = all_count
self.per_page_num = per_page_num
# 总页码
all_pager, tmp = divmod(all_count, per_page_num)
if tmp:
all_pager += 1
self.all_pager = all_pager
self.pager_count = pager_count
self.pager_count_half = int((pager_count - 1) / 2)
@property
def start(self):
return (self.current_page - 1) * self.per_page_num
@property
def end(self):
return self.current_page * self.per_page_num
def page_html(self):
# 如果总页码 < 11个:
if self.all_pager <= self.pager_count:
pager_start = 1
pager_end = self.all_pager + 1
# 总页码 > 11
else:
# 当前页如果<=页面上最多显示11/2个页码
if self.current_page <= self.pager_count_half:
pager_start = 1
pager_end = self.pager_count + 1
# 当前页大于5
else:
# 页码翻到最后
if (self.current_page + self.pager_count_half) > self.all_pager:
pager_end = self.all_pager + 1
pager_start = self.all_pager - self.pager_count + 1
else:
pager_start = self.current_page - self.pager_count_half
pager_end = self.current_page + self.pager_count_half + 1
page_html_list = []
# 添加前面的nav和ul标签
page_html_list.append('''
<nav aria-label='Page navigation>'
<ul class='pagination'>
''')
first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
page_html_list.append(first_page)
if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
else:
prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
page_html_list.append(prev_page)
for i in range(pager_start, pager_end):
if i == self.current_page:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
else:
temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
page_html_list.append(temp)
if self.current_page >= self.all_pager:
next_page = '<li class="disabled"><a href="#">下一页</a></li>'
else:
next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
page_html_list.append(next_page)
last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
page_html_list.append(last_page)
# 尾部添加标签
page_html_list.append('''
</nav>
</ul>
''')
return ''.join(page_html_list)
使用
views.py
from utils import Mypage
def home(request):
current_page = request.GET.get('page') # 获取当前页
all_count = models.Book.objects.count() # 记录的总数量
obj = Mypage.Pagination(current_page, all_count) # 传入参数
page_html = obj.page_html() # 拿到类里面的html样式将它传到前端页面中
book_list = models.Book.objects.all()[obj.start:obj.end] # 查询 切片
return render(request, 'home.html', locals())
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>home</title>
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'CSS/bootstrap.css' %}"/>
<script src="{% static 'JS/bootstrap.min.js' %}"></script>
<script src="{% static 'jQuery/jquery-3.6.0.min.js' %}"></script>
</head>
<body>
<table class="table-striped table text-center">
<thead>
<tr>
<th class="text-center">id</th>
<th class="text-center">书名</th>
</tr>
</thead>
<tbody>
{% for book in book_list %}
<tr>
<td>{{ book.id }}</td>
<td>{{ book.title }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ page_html|safe }}
</body>
</html>
Cookie与Session
http协议的四大特性:
- 基于请求响应
- 基于TCP/UDP协议之上的应用层协议
- 无状态:不能保存用户信息
- 无/短链接:请求一次回应一次,之后断开连接
Cookie
无状态的特性导致http协议无法保存用户信息,为了让它能保存用户信息,就诞生了cookie。cookie将用户需要保存的信息以键值对的形式储存在浏览器上,每次访问服务器时浏览器会自动携带cookie,这样服务器就能通过cookie内容读取到需要信息。
语法
设置cookie:
rep =HttpResponse || render || redirect
rep.set_cookie(key,value,...) # 在返回过程中设置cookie
rep.set_cookie(key,value,max_age=5)
# max_age 表示cookie失效时间 5表示5秒
rep.set_signed_cookie(key,value,salt='加密盐',...)
获取cookie:
request.COOKIES.get(key)
删除cookie:
rep =HttpResponse || render || redirect
rep.delete_cookie(key)
实际应用
创建用户表,用来获取数据
models.py
from django.db import models
# Create your models here.
class UserInfo(models.Model):
username = models.CharField(max_length=32)
password = models.CharField(max_length=32)
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
url(r'^home/', views.home),
url(r'^logout/', views.logout),
url(r'^index/', views.index)
]
views.py
from django.shortcuts import render, redirect, HttpResponse
from app01 import models
# Create your views here.
'''
由于需要判断比较多
所以需要添加装饰器
装饰器添加获取到从哪个页面跳转过来的功能
在跳转到login页面的时候,将跳转之前路径当作参数传到login页面
'''
def auth(func):
def wrapper(request, *args, **kwargs):
# visited_url:获取到 是从哪个页面跳转到登录页面的
visited_url = request.get_full_path()
status = request.COOKIES.get('is_online')
if status: # 判断浏览器是否携带cookie
return func(request, *args, **kwargs)
else:
# 如果跳转到登录页面将获取到的visited_url作为参数传到login页面
return redirect('/login/?visited=%s' % visited_url)
return wrapper
def login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user_obj = models.UserInfo.objects.filter(username=username, password=password).first()
print(user_obj.username)
if not user_obj: # 如果没有查到输入的用户名密码
return redirect('/login/')
else:
'''
没有登录需要跳转到login页面
在login页面 获取到装饰器传来的visited参数
'''
visited_url = request.GET.get('visited')
if visited_url: # 如果有值就表示是从其他页面跳转过来的
rep = redirect(visited_url) # 登录成功后就返回到之前的路径页面
else: # 没有值就回到home页面
rep = redirect('/home/')
rep.set_cookie('is_online', True)
return rep
return render(request, 'login.html')
@auth
def home(request):
# status = request.COOKIES.get('is_online')
# print(status)
# if not status: # 判断浏览器是否携带cookie
# return redirect('/login/')
return render(request, 'home.html')
@auth
def index(request):
return render(request, 'index.html')
def logout(request):
# 点击logout 删除cookie 并返回到登录界面
rep = redirect('/login/')
rep.delete_cookie('is_online')
return rep
模版html文件
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
{% load static %}
<link rel="stylesheet" href="{% static 'CSS/LOGIN.css' %}">
</head>
<body>
<div id="big1">
<h1 style="color: aliceblue">Login</h1>
<form method="post" action="">
<p><input type="text" required="required" placeholder="用户名" name="username"></p>
<p><input type="password" required="required" placeholder="密码" name="password"></p>
<button class="but" type="submit">登录</button>
</form>
</div>
</body>
</html>
home.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>home</title>
{% load static %}
<link rel="stylesheet" href="{% static 'CSS/bootstrap.min.css' %}">
</head>
<body>
<h1>welcome home page</h1>
<a href="/logout/" class="btn btn-danger">注销</a>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
{% load static %}
<link rel="stylesheet" href="{% static 'CSS/bootstrap.min.css' %}">
</head>
<body>
<h1>Here is index page</h1>
<a href="/logout/" class="btn btn-danger ">注销</a>
</body>
</html>
session
cookie可以记录用户状态信息,但cookie的数据保存在浏览器端安全性较差。所以我们通常是通过cookie识别不同的用户,然后在session里保存私密的信息,django.session 表中保存的是浏览器信息,而不是每一个用户的信息。因此, 同一浏览器多个用户请求只保存一条记录(后面覆盖前面),多个浏览器请求才保存多条记录。
session默认过期时间为14天
request.session.set_expiry()
# 整数表示多少秒
# 设置具体时间
session设置语法:
request.session['key'] = value
设置session经历了哪些事?
-
生成了一个随机字符串。
-
操作了数据库
临时把数据存到内存当中。
响应走的的时候操作数据库,将设置的键值对保存到django_session表里面。
-
将随机字符串响应给浏览器。
session获取语法:
request.session.get('key')
获取session经历了哪些事?
- 自动从浏览器中获取cookie信息,即随机字符串。
- 根据随机字符串在django_session表中过滤出记录(没有返回None)。
- 如果有值的情况下那么django会把session数据封装到request.session中。
删除session语法
request.session.delete() # 只删除服务端的 客户端的不删
request.session.flush() # 浏览器和服务端都清空
# 删除 session_data 里的其中一组键值对:
del request.session["key"]
session实际应用
views.py
def s_auth(func):
def wrapper(request, *args, **kwargs):
visited_url = request.get_full_path()
status = request.session.get('is_login')
if status:
return func(request, *args, **kwargs)
else:
return redirect('/s_login/?visited=%s' % visited_url)
return wrapper
def s_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user_obj = models.UserInfo.objects.filter(username=username, password=password).first()
if not user_obj:
return redirect('/s_login/')
else:
visited_url = request.GET.get('visited')
if visited_url:
request.session['is_login'] = True
request.session['user'] = username
return redirect(visited_url)
else:
return redirect('/s_home/')
return render(request, 'login.html')
@s_auth
def s_home(request):
return render(request, 'home.html')
@s_auth
def s_index(request):
return render(request, 'index.html')
def s_logout(request):
del request.session['is_login']
# request.session.flush()
return redirect('/s_login/')
cookie和session语法用法需要注意区分开来。

浙公网安备 33010602011771号