# Django 框架
* 檢視
* URL 映射
* 模型數據
* Template 樣板
* 用戶驗證與權限
* 表單
* 快取
* 管理網站
Django 主要支援 (PostgreSQL、MySQL、Oracle、SQLite)。
當我們安裝完 Django 後,我們就可以在該虛擬環境使用 Django 了, command line 還提供了 django-admin 的指令來創建專案或是設置 application 。
```shell
$ django-admin startproject # 創建一個 project
$ django-admin runserver <port> # 建立一個 localhost server
$ python manage.py startapp app_name # 建立一個 application folder
$ python manage.py makemigrations # 建立資料庫遷移檔(當我們改變 django 的模型資料時)
$ python manage.py migrate # 套用資料庫資料遷移
$ python manage.py createsuperuser # 建立超級使用者
$ python manage.py collectstatic # 從 installed apps 清單中尋找並蒐集所有靜態資源至一處
$ python manage.py test # 進行測試
$ python manage.py shell # 開啟 python shell 並載入 django 環境
$ python manage.py check # 系統檢驗以及常見問題分析
$ django-admin sqlflush
```

Django 是一個後端框架,其接受前端的 HTTP Request 並進入後端處理領域。Django 建立的專案中透過 ul.py 建立 url 映射,我們可以透過 url 導向特定網址並建立不同的 view 來檢視我們的資料。 view 與 model 之間的關係是我們會由 model 來產生不同的 view 來供前端進行檢視,最後輸出 HTTP 的 response 與預先建立的 template 頁面來提供前端框架資料。
當我們新建立一個專案時:
```$ django-admin startproject project_name```
資料夾內會產生一個初始化的專案,樹狀圖如下:
```bash
project/
manage.py
project_name/
__init__.py
settings.py
urls.py
wsgi.py
```
網站的進入點是 project_name folder 底下。
* manage.py: 可以使你使用 command line 與 project 互動。
* __init__.py: 空文件,指示
* setting.py: 所有的網站設置。可以註冊所有創建的 app,也是靜態文件、資料庫配置的地方。
* url.py: 定義 url 到 view 的映射
* wsgi.py: 幫助 Django 網路應用與服務器的通訊
當我們建立一個應用時:
```python3 manage.py startapp catalog```
會產生以下資料夾:
```bash
manage.py
project_name/
catalog/
admin.py
apps.py
models.py
tests.py
views.py
__init__.py
migrations/
```
* migrations 資料夾: 用來存放 migrations。 當你修改 model.py 的數據時,這個文件會自動更新資料庫,牽涉到 對象關係映射器(ORM)
* __init__.py:
* views.py:
* admin.py: 網站管理設置
* tests.py: 撰寫測試的地方
* apps.py: 註冊應用
* models.py: 模型定義
:::info
記得建立完應用後要在 setting.py 的 INSTALLED_APPS 列表裡新增
:::
### URL
```python
urlpattern = [ path('book/<int:id>/', views.book_detail, name='book_detail'),
re_path(r'^index/$', views.index, name='index'),]
# path(route, view, kwargs=None, name=None) route: 定義 URL 路徑 view: view 函數,用來處理請求
```
我們通常會最後會透過 render() 返回一個渲染的頁面
### view
view 為 Django 提供的簡易查詢 api 用來搜尋數據庫,來匹配不同的字串。
```python
from django.http import HttpResponse
def index(request):
context = {
'num_books': num_books,
'num_instances': num_instances,
'num_instances_available': num_instances_available,
'num_authors': num_authors,
}
# Render the HTML template index.html with the data in the context variable
return render(request, 'index.html', context=context)
```
返回可以是一個 HttpRespnse 文本、 render() 渲染或是 redirect() 跳轉新頁面
我們可以在 view 裡攜帶 cookie```request.COOKIES.get(key)``` 取得。第一次使用可使用 request.set_cookie(key, value) 設置。因為 cookie 的字數限制,因此我們會透過 cookie 知道是誰後,使用 session 來保存瀏覽器的訊息。我們可以用 request.session['key'] = value 來設定私密的訊息以及長文本。我們要使用時,以 request.session.get('key') 來存取。以 request.session.flush() 刪除 session 紀錄。
### model
定義模型數據的地方,這裡我們宣告各種不同物件類別來定義模型。
```python
from django.db import models
class Team(models.Model):
team_name = models.CharField(max_length=40)
TEAM_LEVELS = (
('U09', 'Under 09s'),
('U10', 'Under 10s'),
('U11', 'Under 11s'),
... #list other team levels
)
team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')
```
模型其中會定義多個字段,字段的類型可為:
* Char field
* Text field
* Integer field
* Date field
* Email field
* File field
* Auto field
* Foreign Key
* ManyToManyField
我們還可以宣告 class Meta。此類別有用的地方在於可以指定我們查詢的 model 數據紀錄的默認排序。
我們可以使用 ```model.objects.all()``` 來查詢所有的紀錄或是使用```model.filter()```來查詢符合的紀錄。
### template
透過 html 輸出樣板我們可以預先設置樣板,以便輸出填充數據,以下為一個範例:
```html
<!DOCTYPE html>
<html lang="en">
<head>
{% block title %}
<title>Local Library</title>
{% endblock %}
</head>
<body>
{% block sidebar %}
<!-- insert default navigation text for every page -->
{% endblock %}
{% block content %}
<!-- default content text (typically empty) -->
{% endblock %}
</body>
</html>
```
當我們想修改樣板時,我們可以用 extend 來擴展複寫原本的樣板:
```html
{% extends "base_generic.html" %}
{% block content %}
<h1>Local Library Home</h1>
<p>
Welcome to LocalLibrary, a website developed by
<em>Mozilla Developer Network</em>!
</p>
{% endblock %}
```
```html
{% extends "base_generic.html" %}
{% block content %}
<h1>Local Library Home</h1>
<p>
Welcome to LocalLibrary, a website developed by
<em>Mozilla Developer Network</em>!
</p>
<h2>Dynamic content</h2>
<p>The library has the following record counts:</p>
<ul>
<li><strong>Books:</strong> {{ num_books }}</li>
<li><strong>Copies:</strong> {{ num_instances }}</li>
<li><strong>Copies available:</strong> {{ num_instances_available }}</li>
<li><strong>Authors:</strong> {{ num_authors }}</li>
</ul>
{% endblock %}
```
當我們的動態內容需要使用時,需使用 {{ }} 來存取。 {% %} 則是存取模組
if-else 語法 ```{% if condition %} {% endif %}```
for 語法 ```{% for athlete in athlete_list %} {% endfor %}```
empty,在循環為空的時候執行 {% empty %}
以上內容參考自 [MDN](https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Introduction) 以及 [RUNOOB](https://www.runoob.com/django/django-tutorial.html)