圖片上傳及分頁
上傳圖片
在python中進(jìn)行圖片操作,需要安裝包PIL喇闸。
pip install Pillow
在Django中上傳圖片包括兩種方式:
- 在管理頁面admin中上傳圖片
- 自定義form表單中上傳圖片
上傳圖片后可缚,將圖片存儲(chǔ)在服務(wù)器上,然后將圖片的路徑存儲(chǔ)在表中蒂秘。
創(chuàng)建包含圖片的模型類
將模型類的屬性定義成models.ImageField類型提岔。
1)打開booktest/models.py文件,定義模型類PicTest主巍。
class PicTest(models.Model):
pic = models.ImageField(upload_to='booktest/')
2)回到命令行中冠息,生成遷移挪凑。
python manage.py makemigrations
python manage.py migrate
3)打開booktest/migrations/0001_initial.py文件孕索,刪除AreaInfo部分,因?yàn)檫@個(gè)表已經(jīng)存在躏碳。
4)因?yàn)楫?dāng)前沒有定義圖書搞旭、英雄模型類,會(huì)提示“是否刪除”,輸入“no”后回車肄渗,表示不刪除镇眷。
5)打開test5/settings.py文件,設(shè)置圖片保存路徑翎嫡。
因?yàn)閳D片也屬于靜態(tài)文件欠动,所以保存到static目錄下。
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")
6)在static目錄下創(chuàng)建media目錄惑申,再創(chuàng)建應(yīng)用名稱的目錄具伍,此例為booktest。
自定義form表單中上傳圖片
1)打開booktest/views.py文件圈驼,創(chuàng)建視圖pic_upload人芽。
def pic_upload(request):
return render(request,'booktest/pic_upload.html')
2)打開booktest/urls.py文件,配置url绩脆。
url(r'^pic_upload/$', views.pic_upload),
3)在templates/booktest/目錄下創(chuàng)建模板pic_upload.html萤厅。
在模板中定義上傳表單,要求如下:
- form的屬性enctype="multipart/form-data"
- form的method為post
- input的類型為file
<html>
<head>
<title>自定義上傳圖片</title>
</head>
<body>
<form method="post" action="/pic_handle/" enctype="multipart/form-data">
{%csrf_token%}
<input type="file" name="pic"/><br>
<input type="submit" value="上傳">
</form>
</body>
</html>
4)打開booktest/views.py文件靴迫,創(chuàng)建視圖pic_handle惕味,用于接收表單保存圖片。
request對(duì)象的FILES屬性用于接收請(qǐng)求的文件矢劲,包括圖片赦拘。
from django.conf import settings
from django.http import HttpResponse
...
def pic_handle(request):
"""
上傳圖片處理
:param request:
:return:
"""
pic = request.FILES.get('pic')
print(pic.name)
save_path = '{}/booktest/{}'.format(settings.MEDIA_ROOT,pic.name)
with open(save_path,'wb') as f:
for content in pic.chunks():
f.write(content)
# 在數(shù)據(jù)庫中保存上傳記錄
PicTest.objects.create(goods_pic='booktest/{}'.format(pic.name))
return HttpResponse('OK')
5)打開booktest/urls.py文件,配置url芬沉。
url(r'^pic_handle/$', views.pic_handle),
6)運(yùn)行服務(wù)器躺同,在瀏覽器中輸入如下網(wǎng)址:
http://127.0.0.1:8000/pic_upload/
顯示圖片
1)打開booktest/views.py文件,創(chuàng)建視圖pic_show丸逸。
from booktest.models import PicTest
def pic_show(request):
pic=PicTest.objects.get(pk=1)
print(pic.goods_pic)
context={'pic':pic}
return render(request,'booktest/pic_show.html',context)
2)打開booktest/urls.py文件蹋艺,配置url。
url(r'^pic_show/$', views.pic_show),
3)在templates/booktest/目錄下創(chuàng)建模板pic_show.html黄刚。
<html>
<head>
<title>顯示上傳的圖片</title>
</head>
<body>
<img style="width: 380px ; height: 240px" src="/static/media/{{pic.goods_pic}}"/>
</body>
</html>
4)運(yùn)行服務(wù)器捎谨,在瀏覽器中輸入如下網(wǎng)址:
http://127.0.0.1:8000/pic_show/
改為回顯
修改視圖函數(shù)
from django.conf import settings
def pic_handle(request):
"""
上傳圖片處理
:param request:
:return:
"""
pic = request.FILES.get('pic')
print(pic.name)
save_path = '{}/booktest/{}'.format(settings.MEDIA_ROOT,pic.name)
with open(save_path,'wb') as f:
for content in pic.chunks():
f.write(content)
# 在數(shù)據(jù)庫中保存上傳記錄
# PicTest.objects.create(goods_pic='booktest/{}'.format(pic.name))
# return HttpResponse('OK')
pic_file = PicTest.objects.create(goods_pic='booktest/{}'.format(pic.name))
# 獲取路徑
print(pic_file.goods_pic)
context = {'pic': pic_file}
print(context.get('pic'))
return render(request,'booktest/pic_show.html',context)
分頁
Django提供了數(shù)據(jù)分頁的類,這些類被定義在django/core/paginator.py中憔维。 類Paginator用于對(duì)列進(jìn)行一頁n條數(shù)據(jù)的分頁運(yùn)算涛救。類Page用于表示第m頁的數(shù)據(jù)。
Paginator類實(shí)例對(duì)象
- 方法init(列表,int):返回分頁對(duì)象业扒,第一個(gè)參數(shù)為列表數(shù)據(jù)检吆,第二個(gè)參數(shù)為每頁數(shù)據(jù)的條數(shù)。
- 屬性count:返回對(duì)象總數(shù)程储。
- 屬性num_pages:返回頁面總數(shù)蹭沛。
- 屬性page_range:返回頁碼列表臂寝,從1開始,例如[1, 2, 3, 4]摊灭。
- 方法page(m):返回Page類實(shí)例對(duì)象咆贬,表示第m頁的數(shù)據(jù),下標(biāo)以1開始帚呼。
Page類實(shí)例對(duì)象
- 調(diào)用Paginator對(duì)象的page()方法返回Page對(duì)象掏缎,不需要手動(dòng)構(gòu)造。
- 屬性object_list:返回當(dāng)前頁對(duì)象的列表煤杀。
- 屬性number:返回當(dāng)前是第幾頁御毅,從1開始。
- 屬性paginator:當(dāng)前頁對(duì)應(yīng)的Paginator對(duì)象怜珍。
- 方法has_next():如果有下一頁返回True端蛆。
- 方法has_previous():如果有上一頁返回True。
- 方法len():返回當(dāng)前頁面對(duì)象的個(gè)數(shù)酥泛。
示例
1)在areatest/views.py文件中創(chuàng)建視圖page_test今豆。
from django.shortcuts import render
# Create your views here.
from django.core.paginator import Paginator
from areatest.models import AreaInfo
...
#參數(shù)pIndex表示:當(dāng)前要顯示的頁碼
def page_test(request,pIndex):
#查詢所有的地區(qū)信息
list1 = AreaInfo.objects.filter(aParent__isnull=True)
#將地區(qū)信息按一頁10條進(jìn)行分頁
p = Paginator(list1, 10)
#如果當(dāng)前沒有傳遞頁碼信息,則認(rèn)為是第一頁柔袁,這樣寫是為了請(qǐng)求第一頁時(shí)可以不寫頁碼
if pIndex == '':
pIndex = '1'
#通過url匹配的參數(shù)都是字符串類型呆躲,轉(zhuǎn)換成int類型
pIndex = int(pIndex)
#獲取第pIndex頁的數(shù)據(jù)
list2 = p.page(pIndex)
#獲取所有的頁碼信息
plist = p.page_range
#將當(dāng)前頁碼、當(dāng)前頁的數(shù)據(jù)捶索、頁碼信息傳遞到模板中
return render(request, 'areatest/page_test.html', {'list': list2, 'plist': plist, 'pIndex': pIndex})
2)在areatest/urls.py文件中配置url插掂。
url(r'^page(?P<pIndex>[0-9]*)/$', views.page_test),
3)在templates/areatest/目錄下創(chuàng)建page_test.html模板文件。
<html>
<head>
<title>分頁</title>
</head>
<body>
顯示當(dāng)前頁的地區(qū)信息:<br>
<ul>
{%for area in list%}
<li>{{area.id}}--{{area.atitle}}</li>
{%endfor%}
</ul>
<hr>
顯示頁碼信息:當(dāng)前頁碼沒有鏈接腥例,其它頁碼有鏈接<br>
{%for pindex in plist%}
{%if pIndex == pindex%}
{{pindex}}
{%else%}
<a href="/page{{pindex}}/">{{pindex}}</a>
{%endif%}
{%endfor%}
</body>
</html>
4)運(yùn)行服務(wù)器辅甥,在瀏覽器中輸入如下網(wǎng)址:
http://127.0.0.1:8000/page/