上傳圖片
在python中進(jìn)行圖片操作袱贮,需要安裝包PIL加派。
pip install Pillow==3.4.1
在Django中上傳圖片包括兩種方式:
- 在管理頁面admin中上傳圖片
- 自定義form表單中上傳圖片
上傳圖片后,將圖片存儲在服務(wù)器上屑咳,然后將圖片的路徑存儲在表中跛梗。
在管理頁面admin中上傳圖片
創(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)檫@個表已經(jīng)存在莹桅。
4)因?yàn)楫?dāng)前沒有定義圖書昌执、英雄模型類,會提示“是否刪除”,輸入“no”后回車懂拾,表示不刪除煤禽。
- 在booktest.admin目錄下注冊
from booktest.models import PicTest
admin.site.register(PicTest)
(此時運(yùn)行服務(wù)器,上傳圖片岖赋,但圖片將會直接被傳到booktest目錄下檬果,造成混亂,因此....)
6)在static目錄下創(chuàng)建media目錄唐断,再創(chuàng)建應(yīng)用名稱的目錄选脊,此例為booktest。
7)打開test5/settings.py文件脸甘,設(shè)置圖片保存路徑恳啥。
因?yàn)閳D片也屬于靜態(tài)文件,所以保存到static目錄下丹诀。
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")`
8)運(yùn)行服務(wù)器角寸,在瀏覽器中輸入如下網(wǎng)址:
登錄賬戶
選擇圖片
上傳成功
刷新數(shù)據(jù)庫
刷新項(xiàng)目
自定義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
- action="/pic_handle/"
<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對象的FILES屬性用于接收請求的文件疟游,包括圖片呼畸。
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)
# 把圖片存放到static文件夾下的media目錄
# 指定圖片的存儲路徑 static/media/booktest/pic.name
save_path = '{}/booktest/{}'.format(settings.MEDIA_ROOT,pic.name)
# 將文件進(jìn)行寫入
with open(save_path,'wb') as f:
for content in pic.chunks():
f.write(content)
# 在數(shù)據(jù)庫中保存上傳記錄 導(dǎo)入到數(shù)據(jù)庫中
# 絕對路徑
# PicTest.objects.create(pic=save_path)
pic_Test=PicTest.objects.create(pic='booktest/{}'.format(pic.name))
# return HttpResponse('OK')
# 從數(shù)據(jù)庫中調(diào)取剛才上傳的路徑
print(pic_Test.pic)
path = 'pic_Test'
context = {'pic':path}
return render(request, 'booktest/pic_show.html', context=context)
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/
運(yùn)行結(jié)果如下:
顯示圖片
1)打開booktest/views.py文件,添加如下代碼另绩。
# 上傳后在新頁面中返回上傳的圖片
print(pic_Test.pic)
# 從數(shù)據(jù)庫中獲取剛才上傳圖片的路徑
# path = 'pic_Test'
# context = {'pic': path}
context = {'pic': pic_Test}
return render(request, 'booktest/pic_show.html', context=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: 200px ; height: 300px" src="/static/media/{{pic.pic}}"/>
</body>
</html>
4)運(yùn)行服務(wù)器蹦漠,在瀏覽器中輸入如下網(wǎng)址:
http://127.0.0.1:8000/pic_show/
分頁
Django提供了數(shù)據(jù)分頁的類,這些類被定義在django/core/paginator.py中车海。 類Paginator用于對列進(jìn)行一頁n條數(shù)據(jù)的分頁運(yùn)算笛园。類Page用于表示第m頁的數(shù)據(jù)。
Paginator類實(shí)例對象
- 方法init(列表,int):返回分頁對象,第一個參數(shù)為列表數(shù)據(jù)研铆,第二個參數(shù)為每頁數(shù)據(jù)的條數(shù)埋同。
- 屬性count:返回對象總數(shù)。
- 屬性num_pages:返回頁面總數(shù)蚜印。
- 屬性page_range:返回頁碼列表莺禁,從1開始,例如[1, 2, 3, 4]窄赋。
- 方法page(m):返回Page類實(shí)例對象哟冬,表示第m頁的數(shù)據(jù),下標(biāo)以1開始忆绰。
Page類實(shí)例對象
- 調(diào)用Paginator對象的page()方法返回Page對象浩峡,不需要手動構(gòu)造。
- 屬性object_list:返回當(dāng)前頁對象的列表错敢。
- 屬性number:返回當(dāng)前是第幾頁翰灾,從1開始。
- 屬性paginator:當(dāng)前頁對應(yīng)的Paginator對象稚茅。
- 方法has_next():如果有下一頁返回True纸淮。
- 方法has_previous():如果有上一頁返回True。
- 方法len():返回當(dāng)前頁面對象的個數(shù)亚享。
示例
1)在booktest/views.py文件中創(chuàng)建視圖page_test咽块。
from django.shortcuts import render
from django.http import HttpResponse
from django.core.paginator import Paginator
from areatest.models import AreaInfo
# Create your views here.
...
#參數(shù)pIndex表示:當(dāng)前要顯示的頁碼
def page_test(request,pIndex):
# return HttpResponse(pIndex)
# 查詢所有的地區(qū)信息
list1 = AreaInfo.objects.filter(aParent__isnull=True)
# list1 = AreaInfo.objects.all()
# 實(shí)例化 將所有地區(qū)信息按一頁10條進(jìn)行分頁
p = Paginator(list1, 10)
# 如果當(dāng)前沒有傳遞頁碼信息,則展示第一頁(這樣寫是為了請求第一頁時可以不寫頁碼)
if pIndex == '':
pIndex = '1'
# 通過url匹配的參數(shù)都是字符串類型欺税,轉(zhuǎn)換成int類型
pIndex = int(pIndex)
# 獲取第number頁的數(shù)據(jù)
list2 = p.page(pIndex)
# 獲取所有的頁碼信息
plist = p.page_range
# 將當(dāng)前頁的數(shù)據(jù)侈沪、當(dāng)前頁碼、所有頁碼信息-傳遞到模板中
return render(request, 'areatest/page_test.html', {'list': list2, 'pIndex': pIndex, 'plist': plist})
2)在booktest/urls.py文件中配置url晚凿。
url(r'^page(?P<pIndex>[0-9]*)/$', views.page_test),
3)在templates/areatest/目錄下創(chuàng)建page_test.html模板文件亭罪。
<!DOCTYPE html>
<html>
<head>
<title>第{{ pIndex }}頁</title>
</head>
<body>
<h4>顯示當(dāng)前頁的地區(qū)信息:</h4><br>
<ul>
{% for area in list %}
<li>{{ area.id }}------>{{ area.atitle }}</li>
{% endfor %}
</ul>
<hr>
顯示頁碼信息:當(dāng)前頁碼沒有鏈接,其它頁碼有鏈接<br>
{% for pindex in plist %}
{# 當(dāng)前頁面不允許點(diǎn)擊#}
{% 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/
運(yùn)行結(jié)果如下: