# 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'   [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`