摘要
使用Python進行Web項目開發;相對於主流三大Web端解決方案(Java/.NET/PHP) Python在某些方面具有一定的優勢,相對 Java/.NET 有更輕量級的部署方案,相對PHP有更安全開放的環境支持,這些不同點幾乎完全取決於Python語言本身的特性。
0x01: 環境部署
注:開發環境與運行環境的部署需要的基本技能 —— 理論基礎知識扎實,了解相關基本原理,了解具體開發體系;如果不具備這些能力那么遇到問題就會很懵
0x11: Windows+Apache 部署
1. Apache壓縮包直接百度 "Apache" 就能找到官網下載了,飛機票>> Apache24 ;壓縮包解壓至安裝目錄,路徑最好不要含有中文和空格(江湖規矩)
2. httpd.conf 配置文件(apachePath/conf/httpd.conf),Apache部署中最重要的部分,一般只用修改第一條 ServerRoot 就可以了,文檔中 "#" 為行注釋
ServerRoot 改為你的真實路徑(一般在37行上下),Ex: ServerRoot "D:/Program/Apache/Apache24",新版本Apache中采用 "SRVROOT" 宏替換后面所有會用到路徑的地方,新版本修改 Define SRVROOT "c:/Apache24" 為真實路徑可全局替換,較老版本要手動修改以下兩個地方:標識靜態文件路徑(大概在251行上下)以及文件訪問權限,CGI 腳本路徑及訪問權限(大概在368/380行上下);注意:路徑分隔為 "/" 而不是 "\"
Listen 為監聽端口,默認80(通常在60行上下)一般不用修改
LoadModule 為隨Apache啟動加載的模塊(71-185左右),一般不用管
ServerName 取消注釋(225上下),好像是 IANA DNS導航什么的
DocumentRoot 表示靜態文件路徑,見第一條 ServerRoot
ErrorLog 表示記錄文件輸出路徑(300行上下),debug的時候會經常用到這個文件,不更改記錄級別的話提示警告什么的也在里面,我也不知道咋回事兒
LogLevel 表示記錄輸出級別(310行上下),取值文檔中有注釋麻煩自己看
Include 表示要引入的其它配置文件(原文檔中490-530行大量出現),要使用了再詳細了解吧
<Files xx.xx*> 表示文件訪問權限,按類型限制
<IfModule xxx_module> 標簽表示如果加載了 xxx_module 模塊就將其內容作為該模塊的配置
<Directory xxxx> 標簽表示文件夾權限,見第一條 ServerRoot
3. 安裝/卸載系統服務,不安裝沒法用
安裝:管理員權限打開控制台,cd 到 Apache24/bin/ 目錄下,執行 "httpd -k install" 將Apache服務注入系統,可使用 -n 參數指定服務名(一般不要這么干),Ex: "httpd -k install -n "Apache2439" ",如此步安裝過程報錯考慮可能是VC庫版本問題,一般Apache壓縮包中會有一個空文件,文件名表示該版本所依賴的VC庫,若無請自行下載
安裝完成后可到系統服務將該服務 "自動啟動" 改為手動啟動,否則該服務將隨系統開啟而啟動;如果部署到服務器則不用修改
卸載:管理員權限打開控制台,cd 到 Apache24/bin/ 目錄下,執行 "httpd -k uninstall" 卸載服務,若注入服務時使用 -n 參數指定服務名則此處也要用 -n 參數指定
4. 啟動/停止/重啟服務
啟動:管理員權限打開控制台,cd 到 Apache24/bin/ 目錄下,執行 "httpd -k start" 開始運行服務器,若注入服務時使用 -n 參數指定服務名則此處也要用 -n 參數指定
重啟:"httpd -k restart"
停止:"httpd -k stop"
其它:"httpd -h" 可查看httpd支持的所有命令,當然,是英文版的
n. 若上述步驟都沒有什么問題,則訪問 127.0.0.1 就能看到 "It works!" 了(服務器需允許httpd.exe通過防火牆)
0x21: Apache+Django部署
注:Python安裝都不會的就不用繼續看了
1. 運行模式解釋,Apache服務器腳本運行模式有一大堆,具體是咋回事兒我也不是很懂,以下是我對其中一部分的個人理解,若有偏差歡迎指正
CGI: 服務器收到請求后由配置信息找到CGI程序(腳本)路徑,隨后由該程序指定的運行方式運行(直接運行或解析器),然后將執行結果返回給服務器調用處
FCGI: GCI的升級版,改進CGI每次服務器的請求都會調用一次CGI程序體浪費空間和性能的缺點;FCGI創建一個程序執行的管理程序,服務器只與管理程序通信(通信機制一般使用socket)。每次請求會被FGCI管理程序分配給工作進程或線程,由於管理進程事先會啟動多個工作進程/線程,所以省去了事務生成/銷毀的系統開銷
WSGI: FCGI的改進版,管理程序實現方式改為服務器插件而不是使用socket通信,官方文檔中一般使用 Middleware(中間件) 這個概念,可避免端口占用,主要性能提升在於降低通信開銷(內存共享快於socket通信)
2. 中間件 mod_wsgi 是Django在Apache上的一種方案,采用上述WSGI的實現方式
3. Django安裝,建議直接 "pip install django" 安裝,安裝完成后會有 "Success" 之類的提示,可執行 "pip list" 可查看安裝包列表內是否有 "Django x.x.x" 以確認安裝
3.1 pip安裝緩慢原因:下載源在國外,解決:修改下載源,方法:"C:/Users/用戶名" 目錄下創建 "pip" 文件夾,文件夾內創建 "pip.ini" 配置文件,內容為:
[global]
index-url = https://pypi.douban.com/simple/
3.5. Django中一些基礎概念的介紹
項目:一個Web項目的容器,其中包括該Web項目要用到的所有文件,例如靜態文件、Python腳本、數據庫等
應用:Web項目中的一個功能的所有實現,代碼以及數據
項目和應用是多對多的關系,一個項目可由多個應用構成,一個應用可供多個項目使用
4. mod_wsgi 安裝,去Python庫里下載mod_wsgi,模塊版本一定要對應Apache和Python的版本,因為這是一個中間件,就是用來適配兩端模塊的,再送一張飛機票>> mod_wsgi ,下載到的是 whl 文件,使用 "pip install mod_wsgi-xxx.whl" 進行安裝
5. 創建Django項目/應用
控制台執行 "django-admin startproject projName" ,生成一個Django項目,同上 django-admin 也在Python 中 Scripts 目錄下,該命令會在指定目錄生成一個Django項目文件結構,不指定目錄則生成在當前目錄,使用 "django-admin startapp appName" 生成一個應用,貼出自用的一個生成項目和應用的 .bat 腳本

@echo off echo. ** Django ** echo.新建 Django 項目輸入 1 echo.新建 Django 應用輸入 2 set /p cho=輸入后回車: goto tag%cho% :tag1 set /p projName=輸入項目名: django-admin startproject %projName% goto end :tag2 set /p appName=輸入應用名: django-admin startapp %appName% :end echo.請自查當前目錄是否生成文件 pause
6. Apache 適配 mod_wsgi 中間件,修改配置文件 httpd.conf
注:網上一堆找 xxx.so 模塊文件再改上述 httpd.conf 中 LoadModule 是不可行的,因為Python3之后的版本使用的模塊為 pyd 格式
控制台執行 "mod_wsgi-express module-config" ,該命令中的 mod_wsgi-express 在 Python 目錄中 Scripts 文件夾下,如果環境變量 Path 中沒有該 Scripts 的路徑就 cd 過去再用,將得到的3行結果復制下來,粘貼到 Apache 中的 httpd.conf 配置文件末尾,一般是 LoadFile+LoadModule+WSGIPythonHome,分別表示Python解析器路徑/中間件路徑/Python容器路徑,(也可執行 "mod_wsgi-express module-config >> ApachePath/conf/httpd.conf",ApachePath代表Apache安裝根目錄,如果你熟悉命令行應該知道這是個啥)
添加行 " WSGIScriptAlias / "djangoPath/djangoName/wsgi.py" ",該行為Apache找到Django項目提供依據,路徑為Django項目下的 wsgi.py 文件
添加行 " WSGIPythonPath "djangoPath" ",該行為Django項目的容器路徑
配置 wsgi.py 的訪問權限:
<Directory "djangoPath/djangoName">
<Files "wsgi.py">
Require all granted
</Files>
</Directory>
配置靜態文件路徑及訪問權限:
Alias /static "djangoPath/static"
<Directory "djangoPath/static">
AllowOverride None
Options None
Require all granted
</Directory>
配置多媒體文件路徑及訪問權限:(可選)
Alias /media "djangoPath/media"
<Directory "djangoPath/media">
AllowOverride None
Options None
Require all granted
</Directory>
我的配置代碼

#配置wsgi.py訪問權限 WSGIScriptAlias / "D:/Program/Apache/Apache24/htdocs/dj/dj/wsgi.py" WSGIPythonPath "D:/Program/Apache/Apache24/htdocs/dj" <Directory "D:/Program/Apache/Apache24/htdocs/dj/dj"> <Files "wsgi.py"> Require all granted </Files> </Directory> #此項為靜態文件路徑 Alias /static "D:/Program/Apache/Apache24/htdocs/dj/static" #靜態路徑權限配置 <Directory "D:/Program/Apache/Apache24/htdocs/dj/static"> AllowOverride None Options None Require all granted </Directory> #此項為多媒體文件路徑 Alias /media "D:/Program/Apache/Apache24/htdocs/dj/media" #多媒體權限配置 <Directory "D:/Program/Apache/Apache24/htdocs/dj/media"> AllowOverride None Options None Require all granted </Directory>
n. 配置完成以上內容重啟Apache,使用瀏覽器訪問 127.0.0.1 就能看到Django的歡迎界面了(服務器需要在Django項目中setting.py中設置 "ALLOWED_HOSTS=['*']",詳見Django配置文件解析)
0x02: 使用Django進行開發(Python3.7+Django2.2.2)
0x12: Django框架簡介
1. MVT,應該屬於設計模式什么的吧,其實思想和MVC差不多
M(Model): 數據持久層,操作數據庫的
V(View): 視圖層,其實是控制邏輯的
T(Template): 模板層,返回給用戶看的內容
2. 最小文件結構,執行 "django-admin startproject projName" 生成
projName
|-- projName<DIR>
|-- |-- __pycahce__<DIR> #首次運行后自動生成的Python二進制文件
|-- |-- ....pyc
|-- |-- __init__.py #空文件,Python模塊標識
|-- |-- setting.py #該項目的配置信息
|-- |-- urls.py #該項目的所有URL路由
|-- |-- wsgi.py #WSGI的接口??
|-- db.selite3 #項目首次運行后自動生成的數據庫文件(若未修改Django默認使用的數據庫SQLite3)
|-- manage.py #管理該項目的文件
3. 擴展文件結構,自行創建(可選)的文件結構
projName/templates<DIR>: 放置html文件的路徑,Django中成為模板文件
projName/static<DIR>: 放置靜態文件,包括css/js/image
projName/media<DIR>: 放置多媒體文件,大概除了上面兩個其它的文件都可以放這兒吧,也不是很懂這是干嘛的
projName/projName/views.py: 視圖文件,其實名字隨便取,但最好這樣(江湖規矩)
projName/projName/models.py: 模型文件,用來編寫模型的,只能是這個名字好像
0x22: 項目配置,setting.py
BASE_DIR: 項目所在路徑,不常改
SECRET_KEY: 啥密鑰來着??不常改
DEBUG: 調試模式默認為True,用於輸出調試信息,項目上線后應改為False
ALLOWED_HOSTS: 允許通過的地址,上線后一般設置為['*']
INSTALLED_APPS: 安裝的應用,創建應用后需要在此添加
MIDDLEWARE: Django提供的工具集,如CSRF
ROOT_URLCONF: url配置文件,指向項目下的urls.py路由文件,一般不改
TEMPLATES: 模板配置文件
WSGI_APPLICATION: CGI應用實例,一般不改
DATABASES: 數據庫配置
AUTH_PASSWORD_VALIDATORS: 密碼認證配置,一般不改
# 以下為國際化配置
LANGUAGE_CODE: 語言('zh-hans'),設置為中文后Django主頁顯示為中文
TIME_ZONE: 時區('Asia/Shanghai')
USE_I18N: 國際化
USE_I10N: 國際化
USE_TZ: 時間存儲帶時區(False)
STATIC_URL: 靜態文件(CSS/JS/Image/Fonts)位置('/static/')
# 以下為非默認配置
APPEND_SLASH: 自動在url后加 '/', 默認為True
STATICFILES_DIRS: 靜態文件路徑,設置為 (os.path.join(BASE_DIR, 'static'),) ,否則使用Django自帶服務器啟動時不能訪問靜態文件
0x32: 其它常用操作
1. 數據遷移,數據庫生成與更改后都應執行數據遷移指令,控制台執行以下命令
python manage.py makemigrations #創建數據庫文件夾migrations(存在則跳過)
python manage.py migrate #生成數據表及填充權限
創建管理員用戶,用於登錄Django的控制台 127.0.0.1/admin
python manage.py createsuperuser #創建管理員,然后輸入一堆信息就成了
2. 新應用目錄結構,略
3. 啟動Django自帶的Web調試服務器,只能用作調試,並發性為0
控制台cd到Django項目根目錄下,執行 "python manage.py runserver",Django會在127.0.0.1:8000開啟服務器,runserver 可選參數為[ip:port]
4. 新增應用后,應在 setting.py 文件中的 INSTALLED_APPS 中添加該應用的名稱
5. 使用MySQL數據庫,大概記錄一下(我使用的默認的sqlite,沒有用MySQL)
MySQL數據庫安裝,請自行百度
Python MySQL連接驅動安裝,老規矩 "pip install pymysql"
項目中使用MySQL數據庫需要在 __init__.py 中初始化數據庫,代碼為:
import pymysql
pymysql.install_as_MySQLdb()
修改項目 setting.py 文件數據庫部分:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', #Django中Model的實現 'NAME': 'dbName', #數據庫名稱 'USER': 'loginUserName', #登錄用戶 'PASSWORD': 'loginPwd', #登錄密碼 'HOST': '127.0.0.1', #數據庫位置 'PORT': '3306', #數據庫監聽端口 } }
6. setting.py 模板路徑設置,TEMPLATES 中 'DIRS':[BASE_DIR+'/templates',]
7. Django后台管理工具,以下只做簡要介紹,其它請自行查找
訪問 127.0.0.1/admin進入管理頁面(未登錄顯示登錄)
服務器部署 頁面沒有css樣式原因:未作 admin 靜態文件遷移(Apache配置文件中將權限交給Django后沒有決定路徑解析的權限),解決:將 "PythonPath/Lib/site-packages/django/contrib/admin/static" 目錄下的 "admin" 目錄拷至 "ApachePath/htdocs/djangoName/static" 文件夾下
8. Ajax禁止問題,報錯為 "CSRF token missing or incorrect.",原因:CSRF阻止,解決:注釋掉配置文件 setting.py 中 "MIDDLEWARE" 中的 csrf 插件
0x42: 開發部分
1. 核心部分概述
urls.py: Django中的路由系統,說明網址與視圖層(函數調用)的映射關系
views.py: Django中的視圖層,其中放置的函數供路由系統調用
models.py: Django中的模型層,供視圖層調用,用於處理數據持久化,屏蔽相對底層的操作(直接操作SQL語句),當然Django也提供直接執行SQL語句的接口,但不建議你這么干
2. urls.py, views.py, models.py

###########urls.py########### # 當 "urlpatterns" 條目為空或只存在 admin 映射時訪問 127.0.0.1 會映射到Django默認主頁 from django.contrib import admin from django.urls import path from . import views #存在 views.py 文件時可導入視圖文件以使用其中的函數 urlpatterns = [ path('admin/', admin.site.urls), #將.../admin映射到Django管理界面 path('sayHello/', views.sayHello), #調用 sayHello 視圖 ] ###########views.py########### # 使用 "django-admin startapp appName" 創建的應用自動生成該文件 from django.shortcuts import render,HttpResponse,redirect #通常使用這3種方式返回 from . import models #如需使用則手動建立該文件 def sayHello(request): return HttpResponse('Hello Django.') ###########models.py########### #使用 "django-admin startapp appName" 創建的應用自動生成該文件 #修改本文件中內容后執行數據遷移指令,自動生成數據庫結構映射 from django.db import models # 模型建立示例 class User(models.Model): name=models.CharField(primary_key=True,max_length=16) age=models.IntegerField(default=0)
編寫完成后重啟服務器,訪問 127.0.0.1:8000/sayHello 就能看到結果了
3. 一個使用模板+靜態資源的示例,setting.py 中需配置 STATICFILES_DIRS 的值
文件結構
projName
|-- projName<DIR>
|-- __init__.py
|-- settings.py
|-- urls.py
|-- views.py
|-- wsgi.py
|-- static<DIR>
|-- templateTest.css
|-- templateTest.jpg
|-- templateTest.js
|-- templates<DIR>
|-- templateTest
|-- manage.py

##################urls.py################## from django.urls import path from . import views urlpatterns = [ path('<int:pageNum>/',views.template), ] ##################views.py################## from django.shortcuts import render def template(request,pageNum): content={ 'pageNum':pageNum, } return render(request,'templateTest.html',content) ##################templateTest.html################## <!DOCTYPE html> <html> <head> <title>testPage</title> <link rel="stylesheet" type="text/css" href="../static/templateTest.css"> </head> <body> <p>圖片顯示為圓形則css/圖片加載成功</p> <p>彈出對話框則javascript腳本加載成功</p> <p>括號內為地址欄輸入的數字({{pageNum}})</p> <img src="../static/templateTest.jpg"> <script type="text/javascript" src="../static/templateTest.js"></script> </body> </html> ##################templateTest.css################## img{ width: 200px; height: 200px; border-radius: 50%; } ##################templateTest.js################## document.onload=alert('調用javascript');
0x03: 后記
寫得有點久了,95%是在做東西的時候寫的,到發布的時候已經快一個月時間了,其中有些東西現在也記不大清了;當時沒有發布我覺得可能有些重要的地方沒寫完,發布之前我又重新把上面的東西都跑了一次,發現果然是有些東西沒寫到 0.0
這篇文章可能不是描述的最詳細的,但應該是這一套技術比較全面的了,如果有什么問題或建議請回復評論(雖然最后確實頭都寫暈了 555~)
原創文章,轉發請注明