iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
0
Modern Web

慢慢帶你了解Flask系列 第 12

慢慢帶你了解Flask - Day12 網路相簿(8):刪除相片

大家好,我是長風青雲。今天是鐵人賽第十二天。
今天我要說的是相簿裡面的照片刪除~
之前其實我已經劇透過了~我們會使用checkbox的方式把圖片或影片把照片刪除掉。

那我的想法是,我們在album上面新增一個button,意義為編輯模式。
如果我們進入編輯模式,那我們就可以開始進行刪除。
進入編輯模式後,我們的圖片上發會出現checkbox可供選取的小方框,我們選擇完畢後,上方會有,刪除、回到觀賞模式,兩個button。
按刪除,就是真的刪除了。回到觀賞模式,則會將checkbox那些作隱藏。

好,既然我們想完了,那就開始實作吧。

        {% if edit %}
        <td colspan="{{colspan-2}}" class="up" align="right"><input value='刪除' name='edit' type='submit'></td>
        <td  class="up" align="right"><input value='回到觀賞模式' name='edit' type='submit'></td>
        {% else %}
        <td colspan="{{colspan-1}}" align="right" class="up"><input class="button" value='編輯模式' name='edit' type='submit'></td>
        {% endif %}

讓我們在選取資料夾那邊的tr加入這些程式碼。
在這裡我設立了一個class叫作up 是為了美觀所作,所以不用太在意哈哈哈。

然後回到我們的app.py我們要處理觀賞模式與編輯模式的回傳。
這時,我們又需要我們的session,他必須要幫我們記住現在是觀賞模式還是編輯模式。所以我們必須要回到login的地方,又再度加上。

				session['edit']=False

我們預設我們登入時是觀賞模式,接著到我們的album那邊加上。

		elif request.values['edit'] == '編輯模式':
			session['edit']=True
			return render_template('album.html',dirs=dirs,colspan=colspan, \
				filefolder=dirs[2:],files=dict2,username=session.get('username'),edit=session.get('edit'))
		elif request.values['edit'] == '觀賞模式':
			session['edit']=False
			return render_template('album.html',dirs=dirs,colspan=colspan, \
				filefolder=dirs[2:],files=dict2,username=session.get('username'),edit=session.get('edit'))

然後不要忘記了在每一個return 的render_template,我們也都要加入我們的新參數edit= session.get('edit')
接著我們就可以看見他在編輯模式與觀賞模式中作切換了。

那,重頭戲來了。我們如何刪除照片呢?
於是我們在我們每個album的圖片上方加上
(photo部分)

                  {% if edit %}
                    <input type="checkbox" value="{{folder}}-{{image}}#photo" name="delete_box"><br>
                  {% endif %}

(video部分)

                  {% if edit %}
                    <input type="checkbox" value="{{folder}}-{{vlog}}#video" name="delete_box"><br>
                  {% endif %}

於是我們作出測試,現在讓我們看看影片。
Yes
這雖然已經初具樣子了,但我還是不滿意,如果我是在看某一相冊時決定刪除一張相片呢?我不想又看到全部的相冊啊!
於是我們的session又出現了,放心,不是回到login那邊。

	session['now_folder']=dirs[2:]
	return render_template('album.html',dirs=dirs,colspan=colspan, \
		files=dict2, filefolder=dirs[2:],username=session.get('username'),edit=session.get('edit'))

我們將他加在最下方的return上方,還有選擇資料夾的地方。

		if request.values['folder']!='0' and request.values['folder']!='1':
			session['now_folder']=[dirs[int(request.values['folder'])]]
			return render_template('album.html',dirs=dirs,colspan=colspan, files=dict2, \
				filefolder=[dirs[int(request.values['folder'])]],username=session.get('username'),edit=session.get('edit'))
		elif request.values['folder'] =='1':
			session['now_folder']=dirs[2:]
			return render_template('album.html',dirs=dirs, colspan=colspan,\
				filefolder=dirs[2:],files=dict2,username=session.get('username'),edit=session.get('edit'))

我們會告訴他,現在我們所觀看的相冊是哪一個相冊,所以filefolder在進入編輯模式和重回觀賞模式時請維持原先的相冊。
那接下來讓我們再看看他現在的樣子~
Yes
那接下來我們就要開始寫,如果我已經勾選說要刪除的話要怎麼做了。
剛剛在html的checkbox的value不知道大家有沒有注意到,他長得非常奇異。
拿圖片的為例{{folder}}-{{image}}#photo 這是告知app.py,他是哪一個資料夾,是photo還是video,又是什麼名字?
所以到了app.py,我們在進入刪除階段時,前面的部分是這樣寫的。

		elif request.values['edit'] == '刪除':
			flist = request.form.getlist("delete_box")
			for f in flist:
				muru=f[:f.index('-')]
				name=f[f.index('-')+1:f.index('#')]
				format=f[f.index('#')+1:]
				if format == "video":
					os.remove(os.path.join(basepath,session.get('username'),muru,'video',name))
					os.remove(os.path.join(basepath,session.get('username'),muru,'album','video',name[:-4]+'.jpg'))
				else:
					os.remove(os.path.join(basepath,session.get('username'),muru,'photo',name))
					os.remove(os.path.join(basepath,session.get('username'),muru,'album','photo',name))

先是獲得要刪除的圖片後,再將所得的value分成muru(目錄,我這裡使用漢語拼音,意義上其實就是我們一直說的相冊),name是我們此檔案的名稱,format是告訴我們他是影片還是圖片。
然後開始進入刪除行為,使用的是os.remove()。裡面放入所要刪除檔案的路徑,就能將檔案刪除。然後不要忘記因為我們album裡是圖片,而影片的檔名為mp4所以要將他改為jpg

刪除完畢,我們要return,可是還記得先前我說的我們return時的dict2是將我們相簿中擁有的相片影片記錄下來阿,但是我們已經將圖片或影片刪掉了,所以dict2已經是錯誤的了,那該怎麼辦呢?
沒關係!我們在跑一次新的不就好了嗎?
所以刪除的下半部內容是

			dict1={}
			for dir in dirs:
				if dir == "ALL" or dir == '':
					continue
				dict1[dir]={'photo':[],'video':[]}
				path=os.path.join(basepath,session.get('username'),dir,'photo')
				for lists in os.listdir(path):
					dict1[dir]['photo'].append(lists)
				
				path=os.path.join(basepath,session.get('username'),dir,'video')
				for lists in os.listdir(path):
					dict1[dir]['video'].append(lists)
				if dict1[dir]=={'photo':[],'video':[]}:
					shutil.rmtree(os.path.join(basepath,session.get('username'),dir))
					del dict1[dir]
			dirs=os.listdir(os.path.join(basepath,session.get('username')))
			dirs.insert(0,'ALL')
			dirs.insert(0,'')
			if session.get('now_folder') not in dirs:
				session['now_folder']=dirs[2:]

			return render_template('album.html',dirs=dirs,colspan=colspan,username=session.get('username'), \
				filefolder=session.get('now_folder'),files=dict1,edit=session.get('edit'))

這樣我們就成功啦!但在這裡我加了一個東西

if dict1[dir]=={'photo':[],'video':[]}:
					shutil.rmtree(os.path.join(basepath,session.get('username'),dir))
	del dict1[dir]

這句話的意思是,如果我在這個相冊裡面已經沒有照片或影片了,那這個相冊我就不要了。
在這裡我要介紹一下shutil。在Linux,刪除資料夾並不容易,我們要一個一個將我們的檔案刪除完後才可以將這個資料夾刪除,要不然他會說 Cannot Delete foldername: The directory is not empty
shutil的rmtree幫我們解決了這個問題。我只要將我想刪除的資料夾的路徑放進去,我就可以很順利地將所有的檔案刪除。使用shutil需要import shutil
然後我們就可以來看看今天最後的影片了~
Yes

明天我會講作出影片和圖片的超連結,讓我們不是在看縮圖了。
QAQ其實我不太想說相簿了(不過幸好明天就是相簿的最後一天XD)
那麼~また明日~
https://ithelp.ithome.com.tw/upload/images/20190908/20120116SHpaGFX3GM.jpg


上一篇
慢慢帶你了解Flask - Day11 網路相簿(7):album顯示圖片
下一篇
慢慢帶你了解Flask - Day13 網路相簿(9):照片影片串流
系列文
慢慢帶你了解Flask30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言