---
# System prepended metadata

title: Django
tags: [Django]

---

# Django
## 安裝Django

確認Python版本
```
...\> py -m django --version
```
利用pip套件來安裝Django

```
pip install django
```
## 建立新專案
```
...\> django-admin startproject mysite
```
mysite 為專案名稱可以自行設定
### 檔案結構
```
mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        asgi.py
        wsgi.py
```
結構說明:
* mysite/
最外層的專案容器的名稱，可自行更改。
* manage.py
一個命令列工具程式，幫忙 Django 專案中各種互動。
* mysite/
此目錄下是實際的 Python 項目，可以在此導入各種內容。
* mysite/\_\_init\_\_.py
一個空文件，告訴Python該目錄應視為 Python 軟件包。
* mysite/settings.py
Django項目的設定/配置。 Django設定將告訴您所有設定的工作方式。
* mysite/urls.py
Django項目的URL聲明。為此專案網站的“目錄”。
* mysite/asgi.py
一個為專案提供服務(與ASGI兼容的Web服務器)的入口點。
* mysite/wsgi.py
一個為專案提供服務(與WSGI兼容的Web服務器)的入口點。
[WSGI規範](https://wsgi.readthedocs.io/en/latest/)

## 開啟伺服器
```
...\> py manage.py runserver
```
成功會出現
```
Performing system checks...

System check identified no issues (0 silenced).

You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.

March 24, 2020 - 15:50:53
Django version 3.0, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
```
:::success 
更換不同端口
```
...\> py manage.py runserver 8080
```
:::
## 新增功能

:::info
app 在 Django 代表的是一個網站的應用(一項功能)。
根據功能的差異來分類 app。 e.g. 登入功能、點餐功能 ...等等

:::spoiler *Projects vs. apps*
What’s the difference between a project and an app? An app is a Web application that does something – e.g., a Weblog system, a database of public records or a small poll app. A project is a collection of configuration and apps for a particular website. A project can contain multiple apps. An app can be in multiple projects.
:::
```
#加入點餐功能

...\> django-admin startapp orders
```
### APP 資料結構
```
mysite/
    manage.py
    mysite/...
    
    orders/
        __init__.py
        admin.py
        apps.py
        migrations/
            __init__.py
        models.py
        tests.py
        views.py
```
結構說明:
* admin.py : 設定資料庫呈現的模式，之後會跟 models 溝通。
* models.py : 建構你的資料庫型態。
* tests.py : 用來測試你的邏輯是否有遺漏。
* views.py : 寫商業邏輯的地方，跟 urls.py 做呼應並將所需傳達給前端
* urls.py : 讓 views.py 與相對的網站做對應，要自行建立。
* apps.py : 用來區別 app 的一個檔案。
* \_\_init\_\_.py : 告訴 Python 這資料夾是個套件。
* migrations : 記錄 models 裡面所創建的資料庫型態。


#### 編輯 orders/views.py 內容
建立點餐方法及邏輯
#### 建立並在 orders/urls.py 中添加路徑

* orders/urls.py
設定 app 中 urls 對應。(類似區域性概念)
```
from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
```
* mysite/urls.py
修改主要網站站點中 urls 對應。(類似廣域概念)
```
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('orders/', include('orders.urls')),
    path('admin/', admin.site.urls),
]
```
* Path [用法說明](https://docs.djangoproject.com/en/3.0/ref/urls/)

## 修改設定 settings 
* 修改時區為 'Asia/Taipei' &nbsp; [pytz](https://docs.djangoproject.com/en/2.2/_modules/pytz/)
* 設定及管理 [static files](https://docs.djangoproject.com/en/dev/howto/static-files/)

在 mysite/settings.py 修改設定後
```
...\> py manage.py migrate
```


## 更改模型 models 
在 mysite/models.py 建立/修改模型後
```
...\> py manage.py makemigrations mysite
```
所建立的 Migration (資料遷移)檔案，存放在 app 下的 migrations 資料夾中，產生的0001_initial.py檔案(依序編號)。

Ref:
* [manage.py](https://docs.djangoproject.com/en/3.0/ref/django-admin/) 
* [Models 說明文件](https://docs.djangoproject.com/en/3.0/ref/models/)
* 使用 ImageField 需安裝 Pillow library 幫助判斷是否為影像格式。[*Pillow library.*](https://pillow.readthedocs.io/en/latest/handbook/overview.html)

### Models 筆記
::::success
```
# carts.Model 中 cart 修改後 失敗:
python manage.py migrate --fake carts zero
python manage.py migrate carts

#報錯 carts 資料表已存在
sqlite3.OperationalError: table "carts_cart" already exists

#進入 sqlite 操作:
python manage.py dbshell
# 搜尋所有表格 
.table
#確認資料表中的屬性  
.schema carts_cart
#發現屬性不合，刪除資料表重建
DROP TABLE carts_cart
#檢查是否刪除
.table
#發現多了 carts_cart_product
DROP TABLE carts_cart_product
#檢查是否刪除
.table
#完成，離開
.exit

#重新遷移資料庫
python manage.py makemigrations
python manage.py migrate

```
::::
## 視圖(控制) Views
在 /views.py 中定義一些方法，處理響應、計算或控制資訊。

[Base views](https://docs.djangoproject.com/en/3.0/ref/class-based-views/base/)
[Date API reference](https://docs.djangoproject.com/en/3.0/ref/class-based-views/generic-date-based/)
[QuerySet API reference](https://docs.djangoproject.com/en/3.0/ref/models/querysets/)
### Views 筆記
::::success
```
# get_or_create() method; 如果查詢不到 Bob 或 Robert 就創建一個

from django.db.models import Q

obj, created = Person.objects.filter(
    Q(first_name='Bob') | Q(first_name='Robert'),
).get_or_create(last_name='Marley', defaults={'first_name': 'Bob'})
```
::::

## 模板 Templates
* [Django Templates Doc](https://docs.djangoproject.com/en/3.0/topics/templates/)
* [利用 Tag 及 Filter 建立模板。](https://docs.djangoproject.com/en/3.0/ref/templates/builtins/)
能更快速、靈活地建立起網頁，互相調用減少重複製作。
### 簡介
::::info 
- variables
變數，以 {{ 變數名 }} 表示 
- Tag
標籤，{% 標籤名 %}
- Filters
過濾器，{ 標籤 \| 變數 } 將變參數傳入標籤
```
{{ my_date|date:"Y-m-d" }}
```
- include :
網頁模板後，插入當前網頁
```
#插入 navbar.html
{% include 'navbar.html' %}
```
- extend : 
繼承一個網頁
```
#在網頁的一開始聲明繼承 base.html
{% extends 'base.html' %}
```
- block : 
設定一個區塊，名為 content 
```
#設定一個區塊
{% block content %}
    write something ...
{% endblock %}
```
- comment : 
```
#注釋
{# 注釋內容 #}

#多段注釋
{% comment %}
```
::::

### Templates 筆記
::::success
```
#內容太多，想使用 ... 表示時:
{{ content |truncatewords:30 }}    取 content 變數中前30字符，不可用於中文
{{ content |truncatechars:30 }}    取 content 變數中前30字符，可用於中文
#直接切掉，沒有 ...
{{ content |slice:30 }}            取 content 變數中前30字符，可用於中文
```
::::
#### 其他
* [Django REST Framework_quickstart](https://www.django-rest-framework.org/tutorial/quickstart/)
* [To build high-performance Web APIs, focus on the right things. ](https://www.dabapps.com/blog/api-performance-profiling-django-rest-framework/)

###### tags: `Django`

