文章目錄
前言 ´・ᴗ・`
- 本節默認您已經安裝了
- Pycharm
- Django 3.0
- 建議直接用pycharm安裝django 實在不行採用pip
- 本篇測試環境:
- Pycharm 2020.1
- django 3.0.2
- python 3.7
- 本篇內容將會幫助你學習…
- 如何建立自己的第一個網站(有着django小火箭2333)
- django工程目錄的結構 以及相應文件目錄的含義
- 如何注寫自己的應用
- 如何進行數據庫遷移
- ORM 與 原生sql語句的概念
- url 模式的配置 瞭解path() 轉發重定向
- 如何運行網站
框架的基本概念
unopinioned vs opinioned
這是個新詞
意思就是 web框架的一種特點
- opinioned 有主見的
有種web框架擅長搞定特定的web建站問題 但是除了那些擅長點 其他的方面只有很有限的選擇 - un-opinioned 沒主見的
有些web框架 則是所有方面都會讓你自由發展 你都可以自定義 或者說 選擇的範圍很大
scalable
scale 有點"尺寸"相關的概念 意思就是你的web應用 可大可小 適合很方便的調節 而不像傳統的那種 牽一髮而動全身
創建Django工程
我們直接利用pycharm的terminal終端 無需cmd
找到 你想放置django工程的文件夾 比如我選定了django_MDN 文件夾
然後terminal 輸入:
django-admin startproject locallibrary
locallibrary 是項目名稱 你可以隨便改
然後你就會看到這樣的層級目錄:
工程文件解釋
- init.py 只是說明這玩意是個python package(包)
- settings.py 包含所有網站的設定 即
- 註冊所有的web應用
- 所有的靜態文件的地址
- 所有數據庫的配置細節
- urls.py 定義 一些url參數能夠映射到資源的真實地址 或者 是處理此項請求的對象
甚至可以用於映射一些web應用 - wsgi.py 幫助你的web應用與服務器通信的
- manage.py 創建應用 與db交互 啓動服務器等
創建應用
在manage.py 同級目錄 terminal運行:
python manage.py startapp catalog
如果不行 試試
python3 manage.py startapp catalog
py manage.py startapp catalog
py-3 manage.py startapp catalog
之後就能看到pycharm的目錄顯示:
或者你dir 查看目錄內文件 更可信:
應用目錄文件講解
我們的目錄應該是現在這樣的:
locallibrary/
manage.py
locallibrary/
catalog/
admin.py
apps.py
models.py
tests.py
views.py
__init__.py
migrations/
大部分文件都是可以顧名思義的
- views.py 存放view
- view 你可以理解爲 一些對象可以幫我們通過url 找到我們想要的資源 這些的東西 都在view下面 無論是object 繼承於view 還是函數 —— 作爲view的方法
- models.py 存放data models
也就是所謂的ORM —— 我們通過django的model 對數據庫建立模型 然後就像操作對象 對象實例 對象屬性 一樣改變數據庫的表 行 與 列的數據 - tests.py 存放tests
- admin.py 管理網站的一些配置(configuration)
比如你作爲圖書館借閱應用的 admin 你可以在admin 網頁(應該是admin site) 後臺管理書本信息的錄入
意味着 給你一個空間操作這些數據庫信息 只不過不對用戶開放 - apps.py web應用的登記(register)
- migrations folder 當你用python更改數據庫以後 我們需要遷移(migration),意思自動幫你更新數據庫 當然你學過MySQL直接用sql 再事務commit 就是真正更新了
- init.py 照舊 這玩意就是說明這目錄是個py包 可以被工程的別的部分引用
註冊應用
我們已經創建了一個名爲catalog的應用
現在 我們在setting.py 中進行註冊
找到 INSTALLED APP 這個列表 添加上catalog 如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth', # authentic 驗證
'django.contrib.contenttypes',
'django.contrib.sessions', # session 會話
'django.contrib.messages',
'django.contrib.staticfiles',
'catalog'
]
可見django已經幫我們內置了一些應用 比如用戶驗證authentication 會話session 等
添加數據庫信息
還是在setting.py
- MySQL 我就接着我的MySQL教程 來繼續配置數據庫了 如下:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "django", #數據庫名字
'USER':'root', # 一般默認就是root
'PASSWORD':'2333', # 你的密碼
'HOST':'localhost', # 我們現在還是本地服務器跑着學習 後面上真的雲服務器
'PORT':'3306' # 端口號
}
}
你得在mysql創建一個空數據庫,把名字填在“NAME”裏面
- 或者你也可以用默認的sqlite 雖然不適合實際的商業應用 但是自己玩玩還是ok的
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
如果是其他數據庫 你可以參考官網
或者google csdn等等
別的setting
- timezone
我們設成中國的時間咯:
TIME_ZONE = ‘Asia/Shanghai’
TIME_ZONE = ‘Asia/Hong_Kong’
當然你可以設成別的 請看
主要是database name
那邊 - SECRET_KEY. 目前我們一個demo不用管 不過到產品環節的時候就要更改了 涉及安全問題
- DEBUG. 這個就是打印debug的日誌用的 生產環節就設計成False就行了
url.py 配置 (hook up)
我們說過 url.py管得是url參數的映射 具體來說 我們用path()函數 將url的參數對應一個view(視圖)
可以想象一下 我們通過一個url參數 比如\best
去查看NBA MVP的時候 肯定出來的是一個頁面 也就是一個視圖 所以path就是幫我們找到 我們要的網頁
大概有三種用法 後面還會補充更多 這裏只是混個臉熟:)
- 綁定到函數——view.function
- 添加包 from my_app import views
- 書寫正則表達式
'^home'
匹配網址 path(r’^home’, views.home, name=‘home’)
- 綁定到對象_class 繼承於 view
- 添加包 from other_app.views import Home
- 書寫正則表達式
'catalog/<id>/'
匹配網址 path(r’‘catalog//’’, Home.as_view(), name=‘home’) - 注意 id 匹配任何在
catalog/任何字符/
裏面的任何字符 也就是可以傳參 然後用來 比如展現到你的前端網頁上
- 將另一種path連接方式綁定到你想要的連接方式(重新使用)
- import: from django.urls import include, path
- path(‘blog/’, include(‘blog.urls’))
然後當你的path()太多的時候 我們直接用url pattern —— 一個列表 來裝他們 於是我們也可以這麼添加新的path
from django.urls import include
from django.urls import path
urlpatterns += [
path('catalog/', include('catalog.urls')),
]
urlpattern 這個列表包含所有path
注意 django已經默認給我們url pattern 加了一項:
urlpatterns = [
path('admin/', admin.site.urls),
]
這個意思就是 使用admin/
可以訪問所有站點(site)上的url 也就是我們寫在url pattern裏面的一堆path
爲啥要有這句?-- admin是管理者(我們)訪問的 當然應該可以測試所有的url(也是我們寫的url模式)
當url太多該怎麼辦?urlpattern
可以想象 假設你的網站有100個web應用 你應當怎麼管理至少上百個url pattern?
很明顯我們會把一些細小的url匹配模式 放到我們應用裏面去 這就是我們必須在我們的應用catalog
裏面
加上一個url.py 文件 內容如下:
from django.urls import path
from catalog import views
urlpatterns = [
]
那麼 當瀏覽器請求的url 到達我們網站(site) 有點類似根目錄 我們site會調用根目錄的url.py
然後根目錄的url.py就應該轉發(或者說重定向redirect)到 應用catalog
的URL.py 也就是上面我們寫的那個
問題是 如何寫清楚“轉發” 這個操作
我們在根目錄的url.py 裏面寫上:
urlpatterns = [
path('admin/', admin.site.urls), #1
path('catalog/', include('catalog.urls')), #2
path('', RedirectView.as_view(url='/catalog/', permanent=True)), #3
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) #4
第二句就是 意思 你訪問我網站的catalog 我就把這個請求轉給catalog.urls 也就給catalog目錄下的url.py處理
第三句很有意思
- 觀察到 寫url pattern的地方是空的 意思是 所有 url請求
- 因爲我們只有一個應用 乾脆所有網站的事交給catalog去做
- 於是我們把所有url 轉發到 ‘/catalog/’ —— 第二句 我們已經定義過了的 url映射套路
- 所以就是 第二句把訪問catalog的全部踢皮球給
catalog/url.py
- 然後第三句把皮球踢給第二句
catalog/url.py
(從未見過如此厚顏無恥之徒)
第1句不解釋 上面講了
第四句 你或許這麼訪問過 提供vue.js 的官方網站
也就是地址欄輸入網址 得到的是人家的源碼
那麼有沒有想過 我們的服務器也可以這麼提供我們寫的前端代碼呢?比如.html .js .css
這就是返回靜態文件
當然Django倒是默認不支持這麼弄 但是不方便我們debug
於是第四句就是搞定這個的——讓我們的服務器也能返回 前端代碼
總之 最後我們要往根目錄urls.py 寫的代碼是:
from django.contrib import admin
from django import views
from django.urls import include
from django.urls import path
from django.views.generic import RedirectView
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls), #1
path('catalog/', include('catalog.urls')), #2
path('', RedirectView.as_view(url='/catalog/', permanent=True)),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) #4
遷移數據庫 migration
這 是我們運行網站前的最後一步 :)
你會好奇 我們並沒有進行任何數據庫的編寫 那麼 爲啥還遷移數據庫呢?
事實上 django幫你寫好了一部分數據庫的結構 用於後續管理 (別找了 不在model.py裏面^_^)
我們創建的應用 應用相關信息等等 都會保存在django自動創建的數據庫中
另外 希望你別忘了
Django 使用對象關係映射器(ORM)將Django代碼中的模型定義映射到底層數據庫使用的數據結構。
那麼 純ORM 純原生sql 或者兩者混用都是ok得了 個人項目無所謂 團體項目 這個得溝通好:)
這裏 我們要安裝好 mysql-client 庫 直接用pycharm安裝就行
然後
我們在terminal 與manage.py 同級目錄 逐行運行:
python manage.py makemigrations
python manage.py migrate
注意理解這個遷移過程:實際上 make migrations 只是通過我們ORM python代碼 (model.py裏面的) 轉換成sql 語句 然後 真正執行操作的是 migrate
有種說法是 這個migrate 只是我們數據庫版本控制(version control)的一個提綱(schema)而已
其他遷移的命令細節 可以看官網
ORM vs sql
如果我不放心他自動生成的那些sql怎麼辦 也就我不信任ORM呢?
我們可以查看他生成的代碼
首先 找到所有的migrations
運行:
python manage.py showmigrations
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
[X] 0003_logentry_add_action_flag_choices
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
[X] 0008_alter_user_username_max_length
[X] 0009_alter_user_last_name_max_length
[X] 0010_alter_group_name_max_length
[X] 0011_update_proxy_permissions
catalog
(no migrations)
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
sessions
[X] 0001_initial
我們看到熟悉的auth
catalog
sessions
意味着這些都是 已經安裝好的app (登記好的)
如果沒有在setting登記 就會出現:
第二步 我們拿到app名稱 還有相應的migrations的名字 就可以這樣運行:
python manage.py sqlmigrate auth 0001
注意 這個migration原名賊長 幸好我們可用代號 0001
然後我們就得到了:
BEGIN;
--
-- Create model Permission
--
CREATE TABLE "auth_permission" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varch
ar(50) NOT NULL, "content_type_id" integer NOT NULL REFERENCES "django_content_type" ("id") D
EFERRABLE INITIALLY DEFERRED, "codename" varchar(100) NOT NULL);
--
-- Create model Group
--
CREATE TABLE "auth_group" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(80
) NOT NULL UNIQUE);
CREATE TABLE "auth_group_permissions" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "grou
p_id" integer NOT NULL REFERENCES "auth_group" ("id") DEFERRABLE INITIALLY DEFERRED, "permiss
ion_id" integer NOT NULL REFERENCES "auth_permission" ("id") DEFERRABLE INITIALLY DEFERRED);
--
-- Create model User
--
CREATE TABLE "auth_user" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "password" varchar
(128) NOT NULL, "last_login" datetime NOT NULL, "is_superuser" bool NOT NULL, "username" varc
har(30) NOT NULL UNIQUE, "first_name" varchar(30) NOT NULL, "last_name" varchar(30) NOT NULL,
"email" varchar(75) NOT NULL, "is_staff" bool NOT NULL, "is_active" bool NOT NULL, "date_joi
ned" datetime NOT NULL);
CREATE TABLE "auth_user_groups" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "user_id" i
nteger NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "group_id" integ
er NOT NULL REFERENCES "auth_group" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE "auth_user_user_permissions" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "
user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "permi
ssion_id" integer NOT NULL REFERENCES "auth_permission" ("id") DEFERRABLE INITIALLY DEFERRED)
;
CREATE UNIQUE INDEX "auth_permission_content_type_id_codename_01ab375a_uniq" ON "auth_permiss
ion" ("content_type_id", "codename");
CREATE INDEX "auth_permission_content_type_id_2f476e4b" ON "auth_permission" ("content_type_i
d");
CREATE UNIQUE INDEX "auth_group_permissions_group_id_permission_id_0cd325b0_uniq" ON "auth_gr
oup_permissions" ("group_id", "permission_id");
CREATE INDEX "auth_group_permissions_group_id_b120cbf9" ON "auth_group_permissions" ("group_i
d");
CREATE INDEX "auth_group_permissions_permission_id_84c5c92e" ON "auth_group_permissions" ("pe
rmission_id");
CREATE UNIQUE INDEX "auth_user_groups_user_id_group_id_94350c0c_uniq" ON "auth_user_groups" (
"user_id", "group_id");
CREATE INDEX "auth_user_groups_user_id_6a12ed8b" ON "auth_user_groups" ("user_id");
CREATE INDEX "auth_user_groups_group_id_97559544" ON "auth_user_groups" ("group_id");
CREATE UNIQUE INDEX "auth_user_user_permissions_user_id_permission_id_14a6b632_uniq" ON "auth
_user_user_permissions" ("user_id", "permission_id");
CREATE INDEX "auth_user_user_permissions_user_id_a95ead1b" ON "auth_user_user_permissions" ("
user_id");
CREATE INDEX "auth_user_user_permissions_permission_id_1fbb5f2c" ON "auth_user_user_permissio
ns" ("permission_id");
COMMIT;
如果不放心 就這麼檢查
另外 除了我們在ugly的mysql客戶端輸入sql
我們也可以在sqlyog輸入 就好像我們之前做的那樣
當然 還可以調用sql在python的語言接口(implementation)
也就是調用pyMysql庫 這是它的官方文檔
這幾乎就是真的寫sql語句了其實 不再是ORM 對象關係映射(Object Relational Mapping)
那 運行網站吧
python3 manage.py runserver
我們就這樣運行網站吧 本地服務器 默認端口8000
你可以輸入網址到地址欄: http://127.0.0.1:8000/
然後你就會拿到:
注意 這並不意味你成功了:)
忘了嗎?我們的url映射把所有的皮球踢給了catalog/url.py
然而那玩意現在是空的:)
所以他說 你並沒有做任何 configuration on urls pattern
解決問題 很簡單 我們去配置咯
然後這個問題留給下一節 目前 我很享受看到django的小火箭 抖動的樣子:)
將django火箭改成中文
你可以稍微配置一下:
找到根目錄的setting.py:
把這兩句改成中國:
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
然後啓動服務器python manage.py runserver
中文版小火箭:
總結 ´◡`
這一節 我們終於弄出來人生中第一個網站 雖然展現的是django送我們的小火箭
當然不用擔心 這是我們的一小步 全棧領域的一大步
當然對於我來說 這篇文章這麼長能夠通過審覈也是不容易
下一節 我們聊聊數據庫的控制ORM
另外,小姐姐祝賀你完成第一個django 的 demo