From 65a054d603950cffb914abefcb165b4459eaacb3 Mon Sep 17 00:00:00 2001 From: Michelle Date: Sat, 5 May 2018 16:39:01 +0800 Subject: [PATCH 1/8] Update installation to django 2.0 --- README.md | 2 +- django/installation.md | 37 +++++++++++++------------------------ 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index f478ff5..b9d2e15 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ## 學習前準備 在使用這份指南前,請先準備好: -1. [安裝 Python 3.5](http://djangogirlstaipei.herokuapp.com/tutorials/installation/) +1. [安裝 Python 3.4 以上](http://djangogirlstaipei.herokuapp.com/tutorials/installation/) 2. [註冊 PythonAnywhere](https://www.pythonanywhere.com/) diff --git a/django/installation.md b/django/installation.md index 463080e..4f69591 100644 --- a/django/installation.md +++ b/django/installation.md @@ -6,15 +6,15 @@ --- -首先,請開啟**終端機**,確定現在的位置是在**家目錄**底下: +首先,請開啟**終端機**,確定現在的位置是在**家目錄**底下。 -我們先建立一個名為 `djangogirls` 的資料夾 +我們先建立一個名為 `djangogirls` 的資料夾: ``` mkdir djangogirls ``` -並切換至剛剛建立的目錄 +並切換至剛剛建立的目錄: ``` cd djangogirls @@ -82,44 +82,33 @@ Linux 或 OS X 需要使用 `python3` 來建立虛擬環境,指令如下: (djangogirls_venv) ~/djangogirls$ -## 安裝 Django 1.8 最新版本 +## 安裝 Django 2.0 最新版本 ### 開始安裝 Python 3.4 預先安裝了 `pip` 這個強大的套件管理工具,我們將使用它來安裝 Django: ``` -(djangogirls_venv) ~/djangogirls$ pip install "django<1.9" +(djangogirls_venv) ~/djangogirls$ pip install django ``` -這裡需要特別注意,我們使用的指令是 `"django`**`<1.9`**`"`。這樣一來才可以**確保我們安裝的是 Django 1.8 的最新版本** - -輸入了應該會看到如下的訊息,表示安裝成功 +輸入以後應該會看到如下的訊息,表示安裝成功。 ``` -Installing collected packages: django -Successfully installed django-1.8.6 +Installing collected packages: pytz, django +Successfully installed django-2.0.5 pytz-2018.4 ``` -註:如果你看到以 *Fatal error in launcher* 開頭的輸出,而不是上面的安裝成功訊息,請改用 `python -m pip install "django<1.9"` 試試看。之後如果在使用 `pip` 時遇到類似問題,也可以試著在前面加上 `python -m`。 +註:如果你看到以 *Fatal error in launcher* 開頭的輸出,而不是上面的安裝成功訊息,請改用 `python -m pip install django` 試試看。之後如果在使用 `pip` 時遇到類似問題,也可以試著在前面加上 `python -m`。 ### 確認安裝成功 -最後,讓我們最後來測試一下。 - -請在虛擬環境下指令輸入 `python`,進入**互動式命令列**環境 - -``` -(djangogirls_venv) ~/djangogirls$ python -``` - -輸入以下的指令取得 Django 版本資訊: +最後,讓我們來確定一下安裝的版本是否正確,請在虛擬環境下輸入: ``` ->>> import django ->>> django.VERSION -(1, 8, 6, 'final, 0') +(djangogirls_venv) ~/djangogirls$ python -m django --version +2.0.5 ``` -如果看見類似上面的訊息,就代表安裝成功囉! +出現的數字代表虛擬環境中 Django 的版本資訊,如果看見類似上面的訊息,就代表安裝成功囉! \ No newline at end of file From 366d2a3f9ec8a367aacb147f87a0e4e463f600dd Mon Sep 17 00:00:00 2001 From: flywindy Date: Sat, 5 May 2018 17:21:56 +0800 Subject: [PATCH 2/8] Update urls.py to use path function --- django/project_and_app.md | 6 ++++-- django/views_and_urlconfs.md | 21 ++++++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/django/project_and_app.md b/django/project_and_app.md index f2d866d..24988d1 100644 --- a/django/project_and_app.md +++ b/django/project_and_app.md @@ -106,7 +106,7 @@ optional arguments: ``` (djangogirls_venv) ~/djangogirls/mysite$ python manage.py runserver ... -Django version 1.8.5, using settings 'mysite.settings' +Django version 2.0.5, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. ``` @@ -145,6 +145,7 @@ Quit the server with CONTROL-C. trips ├── __init__.py ├── admin.py +├── apps.py ├── migrations ├── models.py ├── tests.py @@ -157,7 +158,7 @@ trips ##新增 app -打開 *mysite/settings.py*,找到 [INSTALLED_APPS](https://docs.djangoproject.com/en/1.8/ref/settings/#std:setting-INSTALLED_APPS),調整如下: +打開 *mysite/settings.py*,找到 [INSTALLED_APPS](https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-INSTALLED_APPS),調整如下: ``` # mysite/settings.py @@ -202,6 +203,7 @@ mysite └── trips ├── __init__.py ├── admin.py + ├── apps.py ├── migrations ├── models.py ├── tests.py diff --git a/django/views_and_urlconfs.md b/django/views_and_urlconfs.md index 9580684..b081d88 100644 --- a/django/views_and_urlconfs.md +++ b/django/views_and_urlconfs.md @@ -19,10 +19,10 @@ Django view 其實是一個 function,**處理 `HttpRequest` 物件,並回傳 `HttpResponse` 物件**,大致說明如下: -- **會收到 `HttpRequest` 參數:** Django 從網頁接收到 request 後,會將 request 中的資訊封裝產生一個 [HttpRequest](https://docs.djangoproject.com/en/1.8/ref/request-response/#httprequest-objects) 物件,並當成第一個參數,傳入對應的 view function。 +- **會收到 `HttpRequest` 參數:** Django 從網頁接收到 request 後,會將 request 中的資訊封裝產生一個 [HttpRequest](https://docs.djangoproject.com/en/2.0/ref/request-response/#httprequest-objects) 物件,並當成第一個參數,傳入對應的 view function。 - **需要回傳 `HttpResponse` 物件:** -[HttpResponse](https://docs.djangoproject.com/en/1.8/ref/request-response/#httpresponse-objects) 物件裡面包含: +[HttpResponse](https://docs.djangoproject.com/en/2.0/ref/request-response/#httpresponse-objects) 物件裡面包含: - `HttpResponse.content` - `HttpResponse.status_code` …等 @@ -80,7 +80,7 @@ from trips.views import hello_world 然後在 `urlpatterns` 中加入下面這行: ```python -url(r'^hello/$', hello_world), +path('hello/', hello_world), ``` 現在 `mysite/urls.py` 的內容應該會像下面這樣: @@ -88,24 +88,23 @@ url(r'^hello/$', hello_world), ```python # mysite/urls.py -from django.conf.urls import include, url from django.contrib import admin +from django.urls import path # Import view functions from trips app. from trips.views import hello_world urlpatterns = [ - url(r'^admin/', include(admin.site.urls)), - url(r'^hello/$', hello_world), + path('admin/', admin.site.urls), + path('hello/', hello_world), ] ``` -以上程式透過 [url()](https://docs.djangoproject.com/en/1.8/ref/urls/#django.conf.urls.url) function 傳入兩個參數 `regex`, `view`: +以上程式透過 [path()](https://docs.djangoproject.com/en/2.0/ref/urls/#django.urls.path) function 傳入兩個參數 `route`, `view`: - url(regex, view) + path(route, view) -- **regex** -- 定義的 URL 規則 - - 規則以 regular expression(正規表示式)來表達 - - `r'^hello/$'` 代表的是 `hello/` 這種 URL +- **route** -- 定義 URL 規則的字串 + - `'hello/'` 代表的是 `http://127.0.0.1:8000/hello/` 這種 URL - **view** -- 對應的 view function - 指的是 `hello_world` 這個 view From da6ee008b2d7b83f186c8b47ab9e8e15422e0ec8 Mon Sep 17 00:00:00 2001 From: flywindy Date: Sat, 5 May 2018 17:36:36 +0800 Subject: [PATCH 3/8] Update template DIRS --- django/models.md | 24 +++++++++++------------- django/templates.md | 15 +++++++++------ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/django/models.md b/django/models.md index feba0af..52e00cb 100644 --- a/django/models.md +++ b/django/models.md @@ -75,29 +75,29 @@ class Post(models.Model): --- - [**Model fields**](https://docs.djangoproject.com/en/1.8/ref/models/fields/) 可為 Django Model 定義不同型態的屬性。 + [**Model Field**](https://docs.djangoproject.com/en/2.0/ref/models/fields/) 可為 Django Model 定義不同型態的屬性。 - **CharField** -- **字串欄位**,適合像 title、location 這種有長度限制的字串。 - **TextField** -- **合放大量文字的欄位** - **URLField** -- **URL 設計的欄位** - **DateTimeField** -- **日期與時間的欄位**,使用時會轉成 Python `datetime` 型別。 -更多 Model Field 與其參數,請參考 [Django 文件 ](https://docs.djangoproject.com/en/1.8/ref/models/fields/) +更多 Model Field 與其參數,請參考 [Django 文件](https://docs.djangoproject.com/en/2.0/ref/models/fields/) --- ## 同步資料庫 -首先執行 [`makemigrations`](https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-makemigrations) 指令: +首先執行 [`makemigrations`](https://docs.djangoproject.com/en/2.0/ref/django-admin/#django-admin-makemigrations) 指令: ``` (djangogirls_venv) ~/djangogirls/mysite$ python manage.py makemigrations Migrations for 'trips': - 0001_initial.py: + trips/migrations/0001_initial.py - Create model Post ``` -這個指令會根據你對 Model 的修改刪除建立一個新的 [migration 檔案](https://docs.djangoproject.com/en/1.8/topics/migrations/#migration-files),讓 `migrate` 指令執行時,可以照著這份紀錄更新資料庫。 +這個指令會根據你對 Model 的修改刪除建立一個新的 [migration 檔案](https://docs.djangoproject.com/en/2.0/topics/migrations/#migration-files),讓 `migrate` 指令執行時,可以照著這份紀錄更新資料庫。 接著用以下的指令,讓 Django 根據上面的紀錄,把 `models.py` 中的欄位寫入資料庫: @@ -109,25 +109,23 @@ Migrations for 'trips': ``` Operations to perform: - Synchronize unmigrated apps: staticfiles, messages - Apply all migrations: sessions, admin, auth, contenttypes -Synchronizing apps without migrations: - Creating tables... - Running deferred SQL... - Installing custom SQL... + Apply all migrations: admin, auth, contenttypes, sessions, trips Running migrations: - Rendering model states... DONE Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK + Applying admin.0002_logentry_remove_auto_add... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK + Applying auth.0007_alter_validators_add_error_messages... OK + Applying auth.0008_alter_user_username_max_length... OK + Applying auth.0009_alter_user_last_name_max_length... OK Applying sessions.0001_initial... OK Applying trips.0001_initial... OK ``` -[`migrate`](https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-migrate) 指令會根據 `INSTALLED_APPS` 的設定,按照 app 順序建立或更新資料表,將你在 models.py 裡的更新跟資料庫同步。 +[`migrate`](https://docs.djangoproject.com/en/2.0/ref/django-admin/#django-admin-migrate) 指令會根據 `INSTALLED_APPS` 的設定,按照 app 順序建立或更新資料表,將你在 models.py 裡的更新跟資料庫同步。 diff --git a/django/templates.md b/django/templates.md index 4493d03..67f817c 100644 --- a/django/templates.md +++ b/django/templates.md @@ -27,7 +27,7 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(BASE_DIR, 'templates').replace('\\', '/')], + 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -44,7 +44,7 @@ TEMPLATES = [ 我們將 `'DIRS'` 原本的`[]`修改成: ```python -[os.path.join(BASE_DIR, 'templates').replace('\\', '/')] +[os.path.join(BASE_DIR, 'templates')] ``` 好讓 Django 找得到剛剛建立的 `templates` 資料夾。 @@ -117,9 +117,12 @@ from django.shortcuts import render def hello_world(request): - return render(request, 'hello_world.html', { - 'current_time': str(datetime.now()), - }) + return render(request, + 'hello_world.html', + { + 'current_time': str(datetime.now()) + } + ) ``` 1. **顯示目前時間:** @@ -138,7 +141,7 @@ def hello_world(request): `render`:產生 HttpResponse 物件。 -[render(request, template_name, dictionary)](https://docs.djangoproject.com/en/1.8/topics/http/shortcuts/#render) +[render(request, template_name, dictionary)](https://docs.djangoproject.com/en/2.0/topics/http/shortcuts/#render) --- From 6099f81662abf43efd7a314540fd37b646a06ac4 Mon Sep 17 00:00:00 2001 From: flywindy Date: Sat, 5 May 2018 17:59:47 +0800 Subject: [PATCH 4/8] Update admin urls --- django/admin.md | 14 ++++++-------- django/orm.md | 16 ++++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/django/admin.md b/django/admin.md index 30e88d5..642bd11 100644 --- a/django/admin.md +++ b/django/admin.md @@ -2,7 +2,7 @@ 大部份網站都設計有管理後台,讓管理者方便新增或異動網站內容。 -而這樣的管理後台,Django 也有內建一個 App -- [**Django Admin**](https://docs.djangoproject.com/en/1.8/ref/contrib/admin/) 。只需要稍微設定,網站就能擁有管理後台功能。 +而這樣的管理後台,Django 也有內建一個 App -- [**Django Admin**](https://docs.djangoproject.com/en/2.0/ref/contrib/admin/) 。只需要稍微設定,網站就能擁有管理後台功能。 前一章,我們學到如何使用 Django Model 抽象地表達資料庫結構。現在,我們要透過 **Django Admin** 看到實際的資料,並跟資料庫進行互動。 @@ -36,14 +36,14 @@ INSTALLED_APPS = ( 我們將管理後台的網址設定為 `/admin/`。確認 `mysite/urls.py` 中的 `urlpatterns` 包含下面這行: ``` -url(r'^admin/', include(admin.site.urls)), +path('admin/', admin.site.urls), ``` ## 建立 superuser 要使用 Django 的管理後台,需要一個管理員帳號。 -使用 [createsuperuser](https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-createsuperuser) 這個指令,建立一個 superuser: +使用 [createsuperuser](https://docs.djangoproject.com/en/2.0/ref/django-admin/#django-admin-createsuperuser) 這個指令,建立一個 superuser: ``` (djangogirls_venv) ~/djangogirls/mysite$ python manage.py createsuperuser @@ -54,7 +54,7 @@ Password (again): Superuser created successfully. ``` -輸入帳號、Email、密碼等資訊,就完成 superuser 的新增了。 +輸入帳號、Email、密碼(必須超過八個字元)等資訊,就完成 superuser 的新增了。 ## 註冊 Model class @@ -65,13 +65,11 @@ Superuser created successfully. ```python # trips/admin.py - from django.contrib import admin -from .models import Post +from .models import Post admin.site.register(Post) - ``` ## 使用管理後台 @@ -101,7 +99,7 @@ admin.site.register(Post) --- -Django 通常以 `Post object` 來表示 Post 物件,但此種顯示不易辨別。我們可以透過 [`def __str__`](https://docs.djangoproject.com/en/1.8/ref/models/instances/#str) 更改 Post 的表示方式。 +Django 通常以 `Post object` 來表示 Post 物件,但此種顯示不易辨別。我們可以透過 [`def __str__`](https://docs.djangoproject.com/en/2.0/ref/models/instances/#str) 更改 Post 的表示方式。 修改 `trips/models.py`: diff --git a/django/orm.md b/django/orm.md index 62cba2c..27cf45a 100644 --- a/django/orm.md +++ b/django/orm.md @@ -27,10 +27,10 @@ 我們一樣可以用 pip 來安裝這個強大的套件: ``` -(djangogirls_venv) ~/djangogirls/mysite$ pip install ipython[terminal] +(djangogirls_venv) ~/djangogirls/mysite$ pip install ipython ``` -安裝完畢後,就可以使用 [shell](https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-shell) 指令,進入 Django Shell: +安裝完畢後,就可以使用 [shell](https://docs.djangoproject.com/en/2.0/ref/django-admin/#django-admin-shell) 指令,進入 Django Shell: ``` (djangogirls_venv) ~/djangogirls/mysite$ python manage.py shell @@ -61,7 +61,7 @@ ### Read 若想顯示所有的 Post ,可以使用 -[all()](https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.all): +[all()](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#django.db.models.query.QuerySet.all): ``` >>> from trips.models import Post @@ -79,16 +79,16 @@ [, ] ``` -- [**get**](https://docs.djangoproject.com/en/1.8/ref/models/querysets/#get):返回符合條件的**唯一一筆資料**。(*注意:*如果找不到符合條件的資料、或是有多筆資料符合條件,都會產生 exception) +- [**get**](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#get):返回符合條件的**唯一一筆資料**。(*注意:*如果找不到符合條件的資料、或是有多筆資料符合條件,都會產生 exception) -- [**filter**](https://docs.djangoproject.com/en/1.8/ref/models/querysets/#filter):返回符合條件的陣列。如果找不到任何資料則會返回空陣列。 +- [**filter**](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#filter):返回符合條件的陣列。如果找不到任何資料則會返回空陣列。 ### Update -當想修改資料時,可以使用 [update](https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.update) 更新一筆或多筆資料: +當想修改資料時,可以使用 [update](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#django.db.models.query.QuerySet.update) 更新一筆或多筆資料: -首先,這裡使用 [contains](https://docs.djangoproject.com/en/1.8/ref/models/querysets/#contains) 針對`title`欄位,篩選出所有標題中包含 `Trip` 字眼的 Post +首先,這裡使用 [contains](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#contains) 針對`title`欄位,篩選出所有標題中包含 `Trip` 字眼的 Post ``` >>> posts = Post.objects.filter(title__contains='Trip') @@ -138,7 +138,7 @@ ### Delete -我們也可以使用 [delete](https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.delete) 刪除資料: +我們也可以使用 [delete](https://docs.djangoproject.com/en/2.0/ref/models/querysets/#django.db.models.query.QuerySet.delete) 刪除資料: 我們試著使用 `delete`,將剛剛的那兩筆 Post 刪除。 From 04075c6a905bb8013325886e124f579b5b2462b6 Mon Sep 17 00:00:00 2001 From: flywindy Date: Sat, 5 May 2018 19:19:33 +0800 Subject: [PATCH 5/8] Update urls.py to use path --- django/dynamic_url.md | 27 +++++++++++---------------- django/template_tags.md | 38 ++++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/django/dynamic_url.md b/django/dynamic_url.md index ef5163e..3521a79 100644 --- a/django/dynamic_url.md +++ b/django/dynamic_url.md @@ -15,12 +15,11 @@ ```python # trips/views.py - -# ... - from django.shortcuts import render + from .models import Post +# ... def post_detail(request, pk): post = Post.objects.get(pk=pk) @@ -52,7 +51,7 @@ from trips.views import hello_world, home, post_detail urlpatterns = [ ... - url(r'^post/(?P\d+)/$', post_detail, name='post_detail'), + path('post//', views.detail, name='detail'), ] ``` @@ -60,25 +59,21 @@ urlpatterns = [ --- -### 使用 Regex 提取部份 URL 為參數 +### 使用 Route 字串將參數從 URL 中提取出來 -我們前面提過,Django 的 URL 是一個 *regular expression (regex)*。Regular expression 語法可用來描述一個字串的樣式。 除了可以表示固定字串之外,還可以用來表示不確定的內容。我們一步一步解釋文章單頁所使用的 URL 設定: +前面提過,如何使用 route 定義 URL 規則,讓 Django 知道該對應到哪個 view function。 除了可以表示固定字串之外,還可以用來表示動態的內容。我們一步一步解釋文章單頁所使用的 URL 設定: ``` -(?P\d+) +'post//' ``` -1. `\d` 代表一個阿拉伯數字。 - -2. `+` 代表「一個以上」。 - - 所以 `\d+` 代表一個以上的阿拉伯數字,例如「0」、「99」、「12345」。可是像「8a」就不符合,因為「a」不是數字。 +1. `post/` 表示 URL 前面為 **post/** 開頭。 -3. `(?P)` 代表「把這一串東西抓出來,命名為 pk。 +2. `int` 定義參數必須為整數。 - 所以 `(?P\d+)` 代表:抓出一個以上阿拉伯數字,並把抓出來的東西取名為 pk。 +3. `` 將傳入的整數,命名為 pk。 -綜合以上的規則,`r'^post/(?P\d+)/$'` 會達成以下的效果: +綜合以上的規則,`'post//'` 會達成以下的效果: URL | 符合結果 ----------|------------------------ @@ -160,7 +155,7 @@ return render(request, 'post.html', {'post': post}) {% url '' arg1= arg2= ...%} ``` -其餘用法可參考[官方文件](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#url)。 +其餘用法可參考[官方文件](https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#url)。 --- diff --git a/django/template_tags.md b/django/template_tags.md index eccab7a..2d0a13e 100644 --- a/django/template_tags.md +++ b/django/template_tags.md @@ -6,7 +6,7 @@ - **重覆 HTML 片段** (for loop) -- 列出所有好友的帳號和顯示圖片 - **格式化 Template 中的變數** -- 日期的格式化等等 -[Django template tags](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/) 讓你可以在 HTML 檔案裡使用類似 Python 的語法,動態存取從 view function 傳過來的變數,或是在顯示到瀏覽器之前幫你做簡單的資料判斷、轉換、計算等等。 +[Django template tags](https://docs.djangoproject.com/en/2.0/ref/templates/builtins/) 讓你可以在 HTML 檔案裡使用類似 Python 的語法,動態存取從 view function 傳過來的變數,或是在顯示到瀏覽器之前幫你做簡單的資料判斷、轉換、計算等等。 --- @@ -34,18 +34,20 @@ ```python # trips/views.py - -# ... - from django.shortcuts import render + from .models import Post +# ... def home(request): post_list = Post.objects.all() - return render(request, 'home.html', { - 'post_list': post_list, - }) + return render(request, + 'home.html', + { + 'post_list': post_list, + } + ) ``` @@ -54,7 +56,7 @@ def home(request): ### 設定首頁的 URL -接下來,我們修改 **urls.py** ,將首頁(正規表達式 `^$`)指向 **home()** 這個 view function: +接下來,我們修改 **urls.py** ,將首頁指向 **home()** 這個 view function: ```python # mysite/urls.py @@ -62,7 +64,7 @@ from trips.views import hello_world, home urlpatterns = [ ... - url(r'^$', home), + path('', home), ] ``` @@ -91,7 +93,7 @@ urlpatterns = [ #### `for` 迴圈 -在寫 Python 時,若想存取 list 裡的每一個元素,我們會使用 `for` 迴圈。而在 Django Template 中,也提供了類似的 template tags -- [{% raw %}{% for %}{% endraw %}](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#for)。 +在寫 Python 時,若想存取 list 裡的每一個元素,我們會使用 `for` 迴圈。而在 Django Template 中,也提供了類似的 template tags -- [{% raw %}{% for %}{% endraw %}](https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#for)。 --- @@ -151,15 +153,15 @@ urlpatterns = [ #### `if`…`else` -另一個常用的 template tags 是 [{% raw %}{% if %}{% endraw %}](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#if) 判斷式,用法如下: +另一個常用的 template tags 是 [{% raw %}{% if %}{% endraw %}](https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#if) 判斷式,用法如下: ```html {% if post.photo %} -
- -
+
+ +
{% else %} -
+
{% endif %} ``` @@ -167,12 +169,12 @@ urlpatterns = [ - 不符合的則放在 `{% raw %}{% else %}{% endraw %}` 區塊裡面 - 最後跟 **for** 一樣,要加上 `{% raw %}{% endif %}{% endraw %}` 作為判斷式結尾。 -在這裡,我們判斷如果 `post.photo` 有值就顯示照片,否則就多加上一個 CSS class `photo-default` 另外處理。 +在這裡,我們判斷如果 `post.photo` 有值就顯示照片,否則就多加上一個 CSS class `thumbnail-default` 另外處理。 ## Template Filter -除了 template tags ,Django 也內建也許多好用的 [template filters](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#built-in-filter-reference)。它能在變數顯示之前幫你做計算、設定預設值,置中、或是截斷過長的內容等等。使用方法如下: +除了 template tags ,Django 也內建也許多好用的 [template filters](https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#built-in-filter-reference)。它能在變數顯示之前幫你做計算、設定預設值,置中、或是截斷過長的內容等等。使用方法如下: `{{|:}}` @@ -182,7 +184,7 @@ urlpatterns = [ #### 變更時間的顯示格式 -在這裡,我們只練習一種很常用的 filter [date](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#date)。它可以將 `datetime` 型別的物件,以指定的時間格式輸出。 +在這裡,我們只練習一種很常用的 filter [date](https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#date)。它可以將 `datetime` 型別的物件,以指定的時間格式輸出。 我們試著將 `created_at` 時間顯示成**年 / 月 / 日**: From b44d7631e84e8f75dad06994e14956367fb8cb2e Mon Sep 17 00:00:00 2001 From: flywindy Date: Sat, 5 May 2018 19:20:07 +0800 Subject: [PATCH 6/8] Update resource --- django/next.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/django/next.md b/django/next.md index a3de1a3..ac20a20 100644 --- a/django/next.md +++ b/django/next.md @@ -7,18 +7,17 @@ - 修改 HTML 與 CSS,調整成你喜歡的樣子 - 為旅遊日記添加新的欄位(例如旅遊日期),並使用 `makemigrations` 和 `migrate` 更新資料庫。 -- 為旅遊日記加入作者(提示:你可能會需要修改 Model,並與 [Django 使用者認證](https://docs.djangoproject.com/en/1.7/topics/auth/) 功能整合) -- 將 HTML 重複的部分獨立出來共用(提示:使用 [Template 繼承](https://docs.djangoproject.com/en/1.7/topics/templates/#template-inheritance)) -- 為每一篇日記加上留言板(提示:[ Django Forms](https://docs.djangoproject.com/en/dev/topics/forms/) 可以幫助你更快速地完成) +- 為旅遊日記加入作者(提示:你可能會需要修改 Model,並與 [Django 使用者認證](https://docs.djangoproject.com/en/2.0/topics/auth/) 功能整合) +- 將 HTML 重複的部分獨立出來共用(提示:使用 [Template 繼承](https://docs.djangoproject.com/en/2.0/topics/templates/#template-inheritance)) +- 為每一篇日記加上留言板(提示:[ Django Forms](https://docs.djangoproject.com/en/2.0/topics/forms/) 可以幫助你更快速地完成) ## 其他學習資源 - [Codecademy](http://www.codecademy.com/learn) -- 透過闖關遊戲方式學習 Python, HTML/CSS, JavaScript -- [Writing your first Django app](https://docs.djangoproject.com/en/1.8/intro/tutorial01/) -- Django 1.8 官方學習指南 -- [Getting Started With Django](http://gettingstartedwithdjango.com/) -- 影片課程 -- [The Django Book](https://django-book.readthedocs.org/en/latest/) -- 雖然 Django 版本不是最新,但相當適合初學者的一本書 -- [Two Scoops of Django: Best Practices for Django](http://twoscoopspress.org/products/two-scoops-of-django-1-8) -- 非常推薦,曾經在 [Taipei.py](http://www.meetup.com/Taipei-py/) 隔週二聚會指定書籍 +- [Writing your first Django app](https://docs.djangoproject.com/en/2.0/intro/tutorial01/) -- Django 2.0 官方學習指南 +- [The Django Book](https://djangobook.com/) -- 非常適合初學者的一本書,目前最新版本為 Django 1.11 LTS +- [Two Scoops of Django: Best Practices for Django](https://www.twoscoopspress.com/products/two-scoops-of-django-1-11) -- Django 的最佳實踐範例(Django 1.11 LTS),曾經為 [Taipei.py](http://www.meetup.com/Taipei-py/) 隔週二聚會指定書籍 - [Django Packages](https://www.djangopackages.com/) -- Django 相關套件彙整平台,提供搜尋和評比 --- From f20c6e39b50835c2783a19dcc20b6b56bbfcc754 Mon Sep 17 00:00:00 2001 From: flywindy Date: Sun, 6 May 2018 21:53:00 +0800 Subject: [PATCH 7/8] Update for comments from TP --- django/admin.md | 5 +++-- django/dynamic_url.md | 2 +- django/installation.md | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/django/admin.md b/django/admin.md index 642bd11..df7c667 100644 --- a/django/admin.md +++ b/django/admin.md @@ -54,7 +54,8 @@ Password (again): Superuser created successfully. ``` -輸入帳號、Email、密碼(必須超過八個字元)等資訊,就完成 superuser 的新增了。 +輸入帳號、Email、密碼等資訊,就完成 superuser 的新增了。 +注意:密碼不能太常見,並且需要超過八個字元。 ## 註冊 Model class @@ -99,7 +100,7 @@ admin.site.register(Post) --- -Django 通常以 `Post object` 來表示 Post 物件,但此種顯示不易辨別。我們可以透過 [`def __str__`](https://docs.djangoproject.com/en/2.0/ref/models/instances/#str) 更改 Post 的表示方式。 +Django 預設以 `Post object` 來表示 Post 物件,但此種顯示不易辨別。我們可以透過 [`def __str__`](https://docs.djangoproject.com/en/2.0/ref/models/instances/#str) 更改 Post 的表示方式。 修改 `trips/models.py`: diff --git a/django/dynamic_url.md b/django/dynamic_url.md index 3521a79..5f7e7ad 100644 --- a/django/dynamic_url.md +++ b/django/dynamic_url.md @@ -51,7 +51,7 @@ from trips.views import hello_world, home, post_detail urlpatterns = [ ... - path('post//', views.detail, name='detail'), + path('post//', post_detail, name='post_detail'), ] ``` diff --git a/django/installation.md b/django/installation.md index 4f69591..65f1c42 100644 --- a/django/installation.md +++ b/django/installation.md @@ -89,7 +89,7 @@ Linux 或 OS X 需要使用 `python3` 來建立虛擬環境,指令如下: Python 3.4 預先安裝了 `pip` 這個強大的套件管理工具,我們將使用它來安裝 Django: ``` -(djangogirls_venv) ~/djangogirls$ pip install django +(djangogirls_venv) ~/djangogirls$ pip install django~=2.0 ``` 輸入以後應該會看到如下的訊息,表示安裝成功。 From ed6f3b8d35fc94ad46d61453ac1d98cf2b9907ae Mon Sep 17 00:00:00 2001 From: flywindy Date: Tue, 15 May 2018 00:09:48 +0800 Subject: [PATCH 8/8] Update render format and small changes --- django/admin.md | 4 ++-- django/models.md | 2 +- django/project_and_app.md | 6 +++--- django/template_tags.md | 11 ++++++----- django/templates.md | 11 ++++++----- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/django/admin.md b/django/admin.md index df7c667..855d64e 100644 --- a/django/admin.md +++ b/django/admin.md @@ -21,10 +21,10 @@ ``` # mysite/settings.py -INSTALLED_APPS = ( +INSTALLED_APPS = [ 'django.contrib.admin', ... -) +] ``` 當你在同步資料庫時,也會建立需要的資料表及欄位。 diff --git a/django/models.md b/django/models.md index 52e00cb..e788438 100644 --- a/django/models.md +++ b/django/models.md @@ -36,7 +36,7 @@ DATABASES = { - **ENGINE** -- 你要使用的資料庫引擎。例如: - MySQL: `django.db.backends.mysql` - SQLite 3: `django.db.backends.sqlite3` - - PostgreSQL: `django.db.backends.postgresql_psycopg2` + - PostgreSQL: `django.db.backends.postgresql` - **NAME** -- 你的資料庫名稱 如果你使用 MySQL 或 PostgreSQL 等等資料庫,可能還要設定它的位置、名稱、使用者等等。不過我們這裡使用的 SQLite 3 不需要這些性質,所以可以省略。 diff --git a/django/project_and_app.md b/django/project_and_app.md index 24988d1..ed13b34 100644 --- a/django/project_and_app.md +++ b/django/project_and_app.md @@ -23,7 +23,7 @@ 首先,使用 `django-admin.py` 來建立第一個 Django project `mysite`: ``` -(djangogirls_venv) ~/djangogirls$ django-admin.py startproject mysite +(djangogirls_venv) ~/djangogirls$ django-admin startproject mysite ``` 此時會多了一個 **mysite** 資料夾。我們切換進去: @@ -167,7 +167,7 @@ trips # Application definition -INSTALLED_APPS = ( +INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -175,7 +175,7 @@ INSTALLED_APPS = ( 'django.contrib.messages', 'django.contrib.staticfiles', 'trips', -) +] ``` 請注意 app 之間有時候需要特定先後順序。在此,我們將自訂的 `trips` 加在最後面。 diff --git a/django/template_tags.md b/django/template_tags.md index 2d0a13e..a3e8382 100644 --- a/django/template_tags.md +++ b/django/template_tags.md @@ -42,11 +42,12 @@ from .models import Post def home(request): post_list = Post.objects.all() - return render(request, - 'home.html', - { - 'post_list': post_list, - } + return render( + request, + 'home.html', + { + 'post_list': post_list, + } ) ``` diff --git a/django/templates.md b/django/templates.md index 67f817c..e37333a 100644 --- a/django/templates.md +++ b/django/templates.md @@ -117,11 +117,12 @@ from django.shortcuts import render def hello_world(request): - return render(request, - 'hello_world.html', - { - 'current_time': str(datetime.now()) - } + return render( + request, + 'hello_world.html', + { + 'current_time': str(datetime.now()) + } ) ```