iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 18
0
Modern Web

慢慢帶你了解Flask系列 第 18

慢慢帶你了解Flask - Day18 個人單字書(5):簽到

大家好,我是長風青雲。我永遠十八今天是第十八天。
今天要講簽到表,而這也是這個單字書最後一天了,剩下的……未來補全吧。
其實第四個實例會和這有相關,畢竟我現在是英文學習者XD。

回歸正題,今天要說簽到。先給你們看看簽到表的日曆圖的樣子
https://ithelp.ithome.com.tw/upload/images/20190914/20120116ZKbemLBF9M.png
左方是我未來打算寫的測驗部分,但我還不知道英文單字測驗該怎麼下手哈哈哈。是要用連連看、輸入單字、選擇題?選擇題是單純測驗單字英選中還是例句挖空選單字?因為不知道該如何測驗,所以暫時就不動手了。
右方就是我們今天的重點,簽到。那我們先來看看HTML的部分吧。
(不要關注我只簽到一天這個事實!)

<div id="calendar">
   {% set week_addr = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] %}
    <table>
    <tr><td colspan="7" style="border-top-style:none;border-left-style:none;border-right-style:none">{{month}}</td></tr>
    <tr>
      {% for addr in week_addr %}
        <th>{{addr}}</th>
      {% endfor %}
    </tr>
      {% for day in cal %}
        {% set count=loop.index-1 %}
        
        {% if count %7 ==0 %}
        <tr>
        {% endif %}
        

        {% if day == 0 %}
         <td>&nbsp</td>
        {% elif [Year,Month,day] in check_day %}
         <td bgcolor="lightcyan">{{day}}</td>
        {% else %}
          <td>{{day}}</td>
        {% endif %}

        {% if count %7 ==6 %}
        </tr>
        {% endif %}
      {% endfor %}
</table>
</div>

驟看是不是看不懂?沒關係我跟你們說說~

{% set week_addr = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'] %}
    <table>
    <tr><td colspan="7" style="border-top-style:none;border-left-style:none;border-right-style:none">{{month}}</td></tr>
    <tr>
      {% for addr in week_addr %}
        <th>{{addr}}</th>
      {% endfor %}
    </tr>

這裡就是我們日曆的第一行,顯示我們星期,由日一二三四五六這樣排序。
而上方的{{month}}則告訴我們現在幾月。

   {% for day in cal %}
        {% set count=loop.index-1 %}
        
        {% if count %7 ==0 %}
        <tr>
        {% endif %}

這裡便是開始將日期放進來了,cal是什麼我們到後端時去說,至少day這個取的應該算是很容易理解。
這邊也就只是說,每七天要換行。

        {% if day == 0 %}
         <td>&nbsp</td>
        {% elif [Year,Month,day] in check_day %}
         <td bgcolor="lightcyan">{{day}}</td>
        {% else %}
          <td>{{day}}</td>
        {% endif %}

day為什麼會為0呢?這是因為每個月的第一天又不一定是由禮拜天開始的。所以那種會使月曆空格幾天的那種不存在的日子,在後端我就將他設為0了。
接著check_day代表已經簽到過的日子。如果今天已經簽到過那他底色就會跟他人有所不同,反之則維持原色(白色)。

{% if count %7 ==6 %}
        </tr>
        {% endif %}
      {% endfor %}
</table>
</div>

而這也就是說,七天結束,請加入</tr>做完結的概念。那就讓我們進到後端吧!

首先我們先import一些module。
import collections,time,calendar
from datetime import datetime
這些待會會用到,我會慢慢說明。

	localtime = time.localtime(time.time())
	year = localtime[0]
	this_month = localtime[1]
	date = localtime[2]

首先,這段的意義就是獲取今天的年月日。
我命名的不錯,我覺得你們一定懂。

	monthRange = calendar.monthrange(year,this_month)
	weekday=monthRange[0]
	if weekday==6:
		weekday=0
	else:
		weekday+=1

calendar.monthrange回傳值有2個,其實我剛剛一看才又發現其實不需要寫成兩行……不過算了。(一個被c++影響到還沒養成python這種新寫法的人)
他輸入的參數是某一年的哪個月,而我這裡輸入的就是今年這月。他回傳的第一個參數是這個月的第一天是星期幾,第二個參數則是這個月有幾天。((以前去寫什麼閏年的題目……嗯……悲從中來))
不過在這裡其實我覺得頗為怪異,他的第一天居然是星期一而不是禮拜天。所以在這裡我就自己將他轉換為我習慣的樣子了。畢竟如果0(第一天)代表的是禮拜一、1(第二天)代表的是禮拜二……我會亂套的哈哈哈。

	cal=[]
	for i in range(0,weekday):
		cal.append(0)
	for i in range(1,monthRange[1]+1):
		cal.append(i)
	remainday=7-(weekday+monthRange[1])%7
	if remainday==7:
		remainday=0
	for i in range(0,remainday):
		cal.append(0)

剛剛在html我說放後端說的cal來了。
首先他就會先加0,直到我們這個月的第一天到來。
接著便是將日期加進cal中。加完後還沒完,畢竟每個月結束也不一定是在禮拜六,所以我們必須將他補全。所以才有remainday產生。(至於為什麼remainday是這樣的計算方式……我是用算出來的……我也不知道該怎麼說明)
算完後在將他加入cal中,我們的cal到時候就會在前端顯示美美的啦~

	if [year,this_month,date] in check[current_user.id]:
		noncheck=False
	else:
		noncheck=True
	if request.method == 'POST':
		if request.values['send'] =="簽到":
			check[current_user.id].append([year,this_month,date])
			with open(os.path.join(os.path.dirname(__file__),'Check_in.json'),'w') as f:
				json.dump(check,f)
	return render_template('user.html',month=month[this_month],Month=this_month,Year=year,cal=cal,check_day=check[current_user.id],noncheck=noncheck,username=users[current_user.id]['nick'])

這一段就是收尾了,noncheck代表著今日簽到否,倘若簽到了就是False,前端的簽到按鈕就會變成disable。而簽到時則將今天的年月日寫入json檔中。回傳前端所需的數值,我們今天的簽到表就完成啦!

啊!不對,我還沒說完我的<style>呢!那就讓我們跳回前端吧!

  table { 
  font-size:16px; 
  width:252px;
  text-align:center;
  border-collapse:collapse;
} 
th { 
  width:36px;
  border:1px solid #DDDDDD;
} 
td {
  width:36px;
  border:1px solid #DDDDDD;
} 
#calendar{
  padding-top:100px;
  padding-right:20px;
  width:270px;
  height: 300px;
  float:right;
}

其實我只是想送給大家這個我覺得漂漂的簽到表,所以一定要放上來。
這其中我要說border-collapse
一般我們在使用table的時候,我這邊不示範了,直接上網路上的圖
圖片來源
https://ithelp.ithome.com.tw/upload/images/20190914/20120116rRZb1EhTXG.png
https://ithelp.ithome.com.tw/upload/images/20190914/20120116zTL6lCjEWR.png
第一個是我們熟悉的邊框樣式,但真的非常醜,絕對不適合做月曆。
所以我就將他用成下方的樣式了。
剩下的我想我就不說了~那今天就到這裡結束吧~
我會將此程式碼放置github,在之後有空時再補全,明天我們要進入新的實例──Secret Talk。
https://ithelp.ithome.com.tw/upload/images/20190914/20120116d4VFbqhT4x.png


上一篇
慢慢帶你了解Flask - Day17 個人單字書(4):增加、查詢、展示單字
下一篇
慢慢帶你了解Flask - Day19 Secret Talk(1):前言 + RSA實作(python to exe)
系列文
慢慢帶你了解Flask30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言