分页
- 分页是指在web页面有大量数据需要显示时,当一页的内容太多不利于阅读和不利于数据提取的情况下,可以分为多页进行显示。
- Django提供了一些类来帮助你管理分页的数据 — 也就是说,数据被分在不同页面中,并带有“上一页/下一页”链接。
- 这些类位于django/core/paginator.py中。
Paginator对象
对象的构造方法
Paginator(object_list, per_page)
参数
- object_list 对象列表
- per_page 每页数据个数
返回值:
- 分页对象
Paginator属性
- count:对象总数
- num_pages:页面总数
- page_range:从1开始的range对象, 用于记录当前面码数
- per_page 每页个数
Paginator方法
Paginator.page(number)
- 参数 number为页码信息(从1开始)
- 返回当前number页对应的页信息
- 如果提供的页码不存在,抛出InvalidPage异常
Paginator异常exception
- InvalidPage:当向page()传入一个无效的页码时抛出
- PageNotAnInteger:当向page()传入一个不是整数的值时抛出
- EmptyPage:当向page()提供一个有效值,但是那个页面上没有任何对象时抛出
Page对象
创建对象 Paginator对象的page()方法返回Page对象,不需要手动构造
Page对象属性
- object_list:当前页上所有对象的列表
- number:当前页的序号,从1开始
- paginator:当前page对象相关的Paginator对象
Page对象方法
- has_next():如果有下一页返回True
- has_previous():如果有上一页返回True
- has_other_pages():如果有上一页或下一页返回True
- next_page_number():返回下一页的页码,如果下一页不存在,抛出InvalidPage异常
- previous_page_number():返回上一页的页码,如果上一页不存在,抛出InvalidPage异常
- len():返回当前页面对象的个数
说明:
- Page 对象是可迭代对象,可以用 for 语句来 访问当前页面中的每个对象
分页示例:
- 视图函数
111def book(request):
2bks = models.Book.objects.all()
3paginator = Paginator(bks, 10)
4print('当前对象的总个数是:', paginator.count)
5print('当前对象的面码范围是:', paginator.page_range)
6print('总页数是:', paginator.num_pages)
7print('每页最大个数:', paginator.per_page)
8
9cur_page = request.GET.get('page', 1) # 得到默认的当前页
10page = paginator.page(cur_page)
11return render(request, 'bookstore/book.html', locals())
- 模板设计
xxxxxxxxxx
341<html>
2<head>
3<title>分页显示</title>
4</head>
5<body>
6{% for b in page %}
7<div>{{ b.title }}</div>
8{% endfor %}
9
10{# 分页功能 #}
11{# 上一页功能 #}
12{% if page.has_previous %}
13<a href="{% url "book" %}?page={{ page.previous_page_number }}">上一页</a>
14{% else %}
15上一页
16{% endif %}
17
18{% for p in paginator.page_range %}
19{% if p == page.number %}
20{{ p }}
21{% else %}
22<a href="{% url "book" %}?page={{ p }}">{{ p }}</a>
23{% endif %}
24{% endfor %}
25
26{#下一页功能#}
27{% if page.has_next %}
28<a href="{% url "book" %}?page={{ page.next_page_number }}">上一页</a>
29{% else %}
30上一页
31{% endif %}
32总页数: {{ page.len }}
33</body>
34</html>
文件上传
文件上传必须为POST提交方式
表单
<form>
中文件上传时必须有带有enctype="multipart/form-data"
时才会包含文件内容数据。表单中用
<input type="file" name="xxx">
标签上传文件- 名字
xxx
对应request.FILES['xxx']
对应的内存缓冲文件流对象。可以能过request.FILES['xxx']
返回的对象获取上传文件数据 file=request.FILES['xxx']
file 绑定文件流对象,可以通过文件流对象的如下信息获取文件数据 file.name 文件名 file.file 文件的字节流数据
- 名字
如下上传文件为图片类型,可以用模块类属性定义成models.ImageField类型
image_file = models.ImageField(upload_to='images/')
- 注意:如果属性类型为ImageField需要安装包Pilow
- pip install Pillow==3.4.1
- 图片存储路径
练习: 在项目根目录下创建media文件夹 图片上传后,会被保存到“/static/media/images/"下 打开settings.py文件,增加media_root项 MEDIA_ROOT=os.path.join(BASE_DIR,"static/media") 使用django后台管理,遇到ImageField类型的属性会出现一个file框,完成文件上传 手动上传的模板代码
xxxxxxxxxx
141<!-- file:static/upload.html -->
2<html>
3<head>
4 <title>文件上传</title>
5 <meta charset="utf-8">
6</head>
7<body>
8 <h1>上传文件</h1>
9 <form method="post" action="/upload" enctype="multipart/form-data">
10 <input type="file" name="myfile"/><br>
11 <input type="submit" value="上传">
12 </form>
13</body>
14</html>
311# file : settings.py
2...
3STATIC_URL = '/static/'
4STATIC_ROOT = os.path.join(BASE_DIR, 'static')
5...
6
7# file urls.py
8urlpatterns = [
9 url(r'^admin/', admin.site.urls),
10 url(r'^upload', views.upload_file)
11]
12urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
13
14
15# file views.py
16from django.http import HttpResponse
17from django.conf import settings
18import os
19
20from django.views.decorators.http import require_POST
21
22def upload_file(request):
23 if request.method == "POST":
24 file = request.FILES['myfile']
25 print("上传文件名是:", file.name)
26
27 filename =os.path.join(settings.MEDIA_ROOT, file.name)
28 with open(filename, 'wb') as f:
29 f.write(file.file.read())
30 return HttpResponse("接收文件成功")
31 return HttpResponse("接收文件失败")