---
# System prepended metadata

title: 網站
tags: [Coding]

---

###### tags: `Coding`
# 網站

## Django
### Django 基本運作邏輯
* Model：資料模組，主要設定是在 models.py 中，即連結後端資料庫的部分，通常包含如何定義與存取資料的程式。例如，定義該網站會員的帳密、郵件、個人資訊等。
* Template：視圖模組，一般常見在 templates 資料夾內放置各種 html 模板，也稱作表現層 (presentation layer)，即前端畫面的呈現，常見的是各種 html templates，像是網站的首頁、分頁、表單等。
* View：控制模組（注意與 MVC 中的 View 不同），主要設定是在 views.py 與 urls.py 中，即介於前後端之間，負責處理用戶請求 (request) 的中繼程式。包含各種互動功能 (action)、表單資料接收、數據分析等。

發出request -> urls尋找相應動作（網址）->執行views中函式，若有連接資料庫，則從models與views溝通得到資料 ->藉由template渲染至前端頁面

### 各檔案功能及系統啟動
* manage.py -- 管理用程式碼，啟動或者新增APP皆藉由此（包含migrate等功能）
* __ name __ 資料夾 -- 與專案名稱相同，放置區域變數
* settings.py(收入在__name__資料夾內) -- 管理專案的全域變數、APP、database、template等
* urls.py -- 網址設定，設定urls對應到的函式
* wsgi.py -- 界面設定檔，用以apache server(推上server 時候Apache會讀取該檔案)

### 建立新專案
```django-admin startproject <PROJECT NAME> #開始新專案，以下假設是Lab_Training```
    
### 啟動
啟動教學（linux)--
於終端機輸入： $ python manage.py runserver

開放外部連結 -- 於setting.py 中輸入（更改）：ALLOWED_HOSTS = ['*'] 則可開放所有電腦網卡IP連線，並且於啟動時改為輸入：$ python manage.py runserver 0.0.0.0:8000
設定完成後，輸入網域的 Public IP (140.116.214.XXX) 與對應的 Port 就可以讓外部連線

### 建立網站（app)
1. built new app:$ python manage.py startapp <app_name>
2. go into setting.py find INSTALLED_APPS{} and add the name of app inside e.q. app_name
inside the app_name folder ,there should be:<br>
a. views -- functions<br>
b. admins -- set the admins<br>
c. models -- for the database <br>
&emsp;therefore if we want to set the url and connect to the views, we have to import views.py in the urls.py and set:path('function_fold/', views.hello_world) into urlpatterns, which showns as 
```
        urlpatterns = [
            path('admin/', admin.site.urls),
            path('hello/', views.hello_world), #新增網址與對應的動作 -> need to def function name hello_world in the views.py  (in the urls.py)
        ]
```
### super user 建立
$ python manage.py createsuperuser

### 讓外部連線
* 對所有電腦內網卡 IP 開放連線<br>
ALLOWED_HOSTS = ['*']
* 動時加入參數：<br>
$ python manage.py runserver 0.0.0.0:8000

### 啟動app設定(基本設定)
#### setting.py
**啟動app**
```
# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'web_tool', # <--新增你的app
)

...

# Internationalization

LANGUAGE_CODE = 'zh-Hant' #語言
TIME_ZONE = 'Asia/Taipei' #時區
USE_I18N = True
USE_TZ = True
```
**template 設定**
```
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'], # <--修改這裡！
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

...

# Static files (CSS, JavaScript, Images)

STATIC_URL = 'static/'
STATICFILES_DIRS = [BASE_DIR / "static"] # <--修改這裡！
```
#### urls.py
```
from django.contrib import admin
from django.urls import path
from web_tool import views #匯入你的 web_tool/view.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', views.hello_world), #新增網址與對應的動作
]
```
#### views.py
```
from django.shortcuts import render
from django.http import HttpResponse #匯入http模組

def hello_world(request):
    return HttpResponse("Hello World!")
```

### DB browser
1. 安裝DB browser
2. 載入資料庫名稱（預設為db.sqlite3)
3. import -> as csv 載入資料
4. 設定keyword(從 modified table)
5. 注意admin內不能import models內的class/function (因為在使用inspectdb時候會覆寫models.py，因此若是此時admin.py內部還有使用到models.py內的class/function則會報錯（無法搜尋到)）
6. if linux system : 在terminal輸入 $ python manage.py inspectdb > < app_name >/models.py
7. 確認models.py 內是否有引入資料，以及primary key

### Data base
* models.py => 引入資料庫內容並且利用class編寫欄位型態以及指定primary key。
* admins.py =>決定在admins（管理員）頁面要如何呈現(並非在主頁面)
* views.py => 將models.py內的函式由此呼叫，並請引入template 內編寫好的html回傳道前端，則可於主頁面上呈現
在models.py內寫完資料庫的建立形式後，需要利用migrate將程式碼與資料庫做同步
``` 
$ python manage.py makemigrations #建立<app_name>/migrations/0001_initial.py
$ python manage.py migrate #根據檔案同步資料庫
```

### Migrate後遇到問題
* sol1.在Migrate 之後如果要再database中添加table，建議先使用DB browser在database內先創建table，後將migrate fold內部的檔案先刪除，再重新makemigration & migrate
* sol2.使用學長的程式碼(summer github)，但是將class Meta之後的內容刪除(models.py內要使用的database欄位），並且一樣刪除migrate fold內部的檔案，並重新makemigration & migrate應也可以解決

### Ajax
* Summer Git hub上的範例中，ajax有關的js檔案內有撰寫url後面的路徑必須和Django內的urls.py中給定與views.ajax_data函式相關的路徑一致
* ex:如果js檔內 -- url: '/new_app/ajax_data/'，則urls.py中路徑必須為 -- path('new_app/ajax_data/', views.ajax_data)（如果呼叫views.ajax_data函式為例)

---
### 動態網站
&emsp;在django內，可以使用動態網站做連結，例如當我在js檔內回傳：<br>
&emsp;`<a href = 'site/{{parameter}}'> </a>`<br>
&emsp;則在urls.py內的程式碼可以利用正則式編寫，以成為動態url，如下：
```
re_path(r'site/(?P<pk>.+)',views.function)
```
&emsp;在上式中，`(?P<pk>.+)`代表參數且名稱為pk(被包在<>內)，在<>外的.+代表正則表達是辨別所有字元，若要辨別數字則用\d+，英文則用\s+（+號代表複數），而（?P）則告知此地方為參數，因此在view.py內傳入參數則要加上pk如下：
```
def function(request,pk):
    try:
        id = pk
    except:
        pass
    return render(request,'output.html',locals())
```
### Bug repair
&emsp; 如果今天更改完JS檔案後，但是單純按F5之後頁面卻沒有相對應的改變，此時可以按ctrl+F5做更進一步的重製，如此便可以完全reset讀取到更改完的js檔案。（因為ctrl+F5會忽略緩存內容）

---------------------
## Javascript / CSS /Bootstrap
### CSS
#### CSS - 一種風格頁面語言，用以將html內的元素套用上不同的風格
<a href = 'https://www.w3schools.com/css/'> css reference</a>
<a href = 'https://www.toodoo.com/db/color.html'> 色碼表</a>
ex:想要將html內段落的部份加上紅色字體，則會寫為：
>p {
    color :red;
}

&emsp;上述中p為html的段落元素，color指定要改變的風格，red指定風格的效果。

&emsp;要在html檔案內，附加css則需要在html檔的head部份內，利用link引入css檔案，如下：
> <link href="styles/style.css" rel="stylesheet" type="text/css"> 
&emsp;link當中的rel指定了屬性，這邊指定為stylesheet告訴程式說是用來改變style，其餘還可指定為icon代表圖標等等,而type則是定義連結內容，其餘可參考<a href = 'https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/link'> link </a>。

&emsp;css 在編寫時可同時指定多個元素做更改，或是多個更改風格，如下：
> p {
  color: red;
  width: 500px;
  border: 1px solid black;
}

>p,li,h1 {
  color: red;
}

&emsp; css 布局基本基於box的形式
<img src = 'https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/CSS_basics/box-model.png'>

* padding - 文字周圍的空白區域
* border - padding外圍的實線
* margin - 元素外部的空間



----------------------------
## HTML

### HTML為一種超文本'標記語言'，而'非程式語言'
<a href = 'https://tw.alphacamp.co/blog/html-guide'> html reference </a>
<a href = 'https://www.csie.ntu.edu.tw/~r91112/myDownload/WEB/html.html'>整理表</a>
html 常見基本語法：

> 宣告：至於文件頂端
> <!DOCTYPE html>

> 標頭：設定網頁的基本資訊，而不會顯示於網頁上（css,bootstrap,JS等等）
> <html> ... </html>

>包圍：顯示給用戶端看到的內容
> <body> ...</body>

html 常見標籤：
* 標題：h1, h2, h3, h4, h5, h6
* 文字段落：p
* 清單：ul-沒有排序, ol-排序, li (直接看程式碼)
> <ul> <li>a <li>b </ul> <ol> <li>a <li>b </ol>
* 強調語氣：em - 斜體 , strong - 粗體
* 換行：br
* 水平線：hr
* 超連結：a
* 圖片：img
* 區域：div, span
* 表格：table, tr, th, td
* 表單：form, label, input
* 空格：& emsp; (&和e無空格)

<img src = 'https://uploads-ssl.webflow.com/60d29cc33f302e8be91cf0e2/61aee1b0d86fbe0a597a5c3f_60d29cc33f302eef0d1d0271_html-basic.png'>

### SVG(向量圖)
**SVG 中的屬性值必須使用雙引號「""」，即便該值是數字。**


---------------------------------------------------
## Application Program Interface(API)
&emsp; API主要工作用於當作溝通橋樑，當我們需要在不同程式間溝通時，則就需要API當作中間人，當我們發出request，API接受request並發送給程式，之後API得到程式所給予的response並且回傳給我。
ex:例如當使用者在網頁上輸入想要查詢的資料時，API便會將這個要求（request）發送到後端的資料庫，並且當資料庫中查詢到資料後，API會再將這個結果（response)傳送回前段，經由前端顯示資料給使用者。

{%youtube zvKadd9Cflc%}


-----
## 網站協定
<a href="https://ithelp.ithome.com.tw/m/articles/10275433">網路運作</a>
<a href = "https://ithelp.ithome.com.tw/articles/10246327">reference2
</a>
### TCP/IP
&emsp;TCP/IP協定由下列兩者組成
* TCP -- 傳輸控制協定(Transmission Control Protocol)，主要處理連線的穩定性
* IP -- 網際網路協定(Internel Protocol)，負責把訊息定義網路上的地址

此兩者協定主要功能為將現今網路的運行方式實行標準化，包含:
* 封裝
* 定址
* 傳輸
* 路由
* 接收

---
### TCP
&emsp;常見包含HTTP request，通常會於標頭檔(header)加上method,content-type等屬性，主要為確保資料抵達目的地、資料傳輸順序相同、資料無損、流量控制。<br>
&emsp;在通訊過程中，會將過程以協定堆疊的方式抽象化為四個抽象層，在每一層的傳輸過程中會被覆加上所需要的資訊(以header的形式加上)，下面以line傳輸訊息作為譬喻:<br>
* 應用層 - 純訊息
* 傳輸層 - 從應用層接收純訊息，並於外層加上連接阜等資訊
* 網路互連層 - 接收從傳輸層傳下的資訊，並於外層包上ip位置等資訊
* 網路存取層 (Network Access) - 接收從網路互連層傳下的資訊，並於外層包上MAC位置等資訊

#### TCP 連線及連接埠
&emsp;會於兩端點建立連線(Socket Connection)，於來源以及目的地個指定一個連接埠（Port），作為確定的連線編號，在運作時，伺服器會開啟一個專門為HTTP開啟的port，並等待傳輸，等待過程稱為監聽，而另一要連接的設備，會於自身無使用的Port作為端口，連接到伺服器上的Port80，建立合法的TCP連線。
**註解:由於TCP存放Port的長度只有16bits，因此合法數字介於1~65535間**
#### TCP的三向交握
1. 提出連線請求，並確保對方有收到請求 (確認我方到對方的網路是通的)
2. 對方回傳同意請求，並發送我方接少到回應時回傳資訊 (回應是否建立連線)
3. 若接收到對方回傳資訊，我方回傳資訊 (最後讓對方知道，我方到對方的路徑是通的)

幾次的交握訊息中，包含有「序列號碼」(sequence number)以及「確認號碼」(acknowledgement number)，且由於IP協定會限制每次傳輸大小，因此若今天傳輸資料過大時，會被切分成個別小份，並藉由TCP序列號碼紀錄，如下:<br>
<img src = 'https://i.imgur.com/TMsfcLD.png'>
於接收到序列號後，對方會回傳確認號，告知下次傳輸時的希望序列號。

---
### IP
#### 基本設定
&emsp;IP位置為四組數字組成(ex:192.168.0.1)，因此可是為一組32bits的數字（4 bytes)，並轉為二進制做後續處理。
#### 浮動與固定IP
* 浮動ip:有身份代碼，但身份代碼會隨時間變換，不容易被定位到
* 固定ip:固定不變得身份代碼，容易被定位到
* 私有ip(虛擬ip):只能虛擬使用，不能作為上網時的公開位置
    * 10.0.0.0 - 10.255.255.255
    * 172.16.0.0 - 172.31.255.255
    * 192.168.0.0 - 192.168.255.255
---
### 子網路遮罩
&emsp;藉由bitwise的AND運算達到辨別效果，如下:
1. 先將IP轉為二進制:
<img src = "https://i.imgur.com/zX817mq.png"><br>
2. 將三個IP位置對子網路遮罩做bitwiseAND運算:
<img src = "https://i.imgur.com/ut8ApMn.png"><br>
3. 得到結果:前兩者在相同子網路內，第三者在不同的子網路。
---

### DNS
&emsp;為Domain Name System（網域名稱系統)的縮寫，通常為網址https://後面那段，其主要功能為網域名稱與IP間的翻譯。
<img src = "https://i.imgur.com/QZeX9o7.png"><br>

---
### Apache 簡介
&emsp;主要功能為作為兩個終端使用者（網站使用者以及管理員）之間的中介，例如電話的轉接接線員等，會監聽欲瀏覽器傳入的請求，並於文檔位置查詢該檔案，若該檔案存在，則會進一步將請求傳入瀏覽器內，主要用以應付來自不同使用者的傳入請求。

### Apache 優缺點
**優點**
1. 開源且免費，甚至可用於商業用途。
2. 可靠、穩定的軟體。
3. 經常更新的安全補丁。
4. 由於其基於模塊的結構而靈活。
5. 易於配置，對初學者友好。
6. 跨平台（適用於 Unix 和 Windows 伺服器）。
7. 靜態文件的最佳交付能力以及與任何編寫程式語言（PHP、Python 等）的兼容性
8. 可與WordPress網站一起使用。
9. 龐大的社區和在出現任何問題時易於獲得的支持。

**缺點**
1. 流量非常大的網站上的性能問題。
2. 太多的配置選項會導致安全漏洞。

### URL
&emsp;藉由固定的url格式可以向網站請求需求
http - 有加密
https - 無加密

### Django & Apahce
&emsp;在Django內的runserver，所建立的是一個小型，非生產等級(non-production)的網站伺服器，主要用以內部網站開發測試使用，當今天正式上市的時，使用人數的增加可能會無法正常運行，因此須配合生產等級的網站伺服器使用，如Apache、Nginx等。