大家好,我是長風青雲。我永遠十八今天是第十八天。
今天要講簽到表,而這也是這個單字書最後一天了,剩下的……未來補全吧。
其實第四個實例會和這有相關,畢竟我現在是英文學習者XD。
回歸正題,今天要說簽到。先給你們看看簽到表的日曆圖的樣子
左方是我未來打算寫的測驗部分,但我還不知道英文單字測驗該怎麼下手哈哈哈。是要用連連看、輸入單字、選擇題?選擇題是單純測驗單字英選中還是例句挖空選單字?因為不知道該如何測驗,所以暫時就不動手了。
右方就是我們今天的重點,簽到。那我們先來看看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> </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> </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的時候,我這邊不示範了,直接上網路上的圖
圖片來源
第一個是我們熟悉的邊框樣式,但真的非常醜,絕對不適合做月曆。
所以我就將他用成下方的樣式了。
剩下的我想我就不說了~那今天就到這裡結束吧~
我會將此程式碼放置github,在之後有空時再補全,明天我們要進入新的實例──Secret Talk。