#4. 虛擬環境 ##4.1 概念 以前安裝python包的命令: sudo pip3 install 包名 包的安裝路徑:/usr/local/lib/python3.5/dist-packagescss
在同一個python環境中安裝同一個包的不一樣版本,後安裝的包會把原來安裝的包覆蓋掉。這樣,若是同一臺機器上兩個項目依賴於相同包的不一樣版本,則會致使一些項目運行失敗。 解決的方案就是:虛擬環境。
虛擬環境是真實python環境的複製版本。 在虛擬環境中使用的python是複製的python,安裝python包也是安裝在複製的python中。 ##4.2 安裝和配置 安裝虛擬環境的命令:html
- 1)sudo pip install virtualenv #安裝虛擬環境
- 2)sudo pip install virtualenvwrapper #安裝虛擬環境擴展包
- 3)編輯/home目錄下面的.bashrc文件,添加下面兩行。
export WORKON_HOME=$HOME/.virtualenvs source /usr/local/bin/virtualenvwrapper.sh
-
4)使用source .bashrc使其生效一下。 ##4.3 使用python
-
建立虛擬環境命令:mkvirtualenv 虛擬環境名mysql
-
建立python3虛擬環境:mkvirtualenv -p python3 evn_py3web
- 建立python3虛擬環境名,# 在建立虛擬環境時,必須保證有網
-
進入虛擬環境工做:workon 虛擬環境名正則表達式
-
查看機器上有多少個虛擬環境:workon 空格 + 兩個tab鍵sql
-
退出虛擬環境:deactivateshell
-
刪除虛擬環境:rmvirtualenv 虛擬環境名數據庫
-
虛擬環境下安裝包的命令:pip install 包名
注意:不能使用sudo pip install 包名,這個命令會把包安裝到真實的主機環境上而不是安裝到虛擬環境中。django -
查看虛擬環境中安裝了哪些python包:
pip list pip freeze
- 安裝django環境:pip install django==3.0.3
- 若是網很差,會報錯:在python中安裝包出現Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))
-- 參考連接1
pip install django==3.0.3 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
拓展: apt-get install 軟件 pip install python包名 #5. 項目建立 ##5.1 建立Django項目
-
命令:django-admin startproject 項目名(test1)
注意:建立應用必須先進入虛擬環境。
-
tree可查看項目目錄
-
項目目錄以下:
- __init__.py: 說明test1是一個python包。
- settings.py: 項目的配置文件。
- urls.py: 進行url路由的配置。
- wsgi.py: web服務器和Django交互的入口。
- manage.py: 項目的管理文件。 ##5.2 建立Django應用 一個項目由不少個應用組成的,每個應用完成一個功能模塊。
-
建立應用的命令以下:python manage.py startapp 應用名(booktest) 注意:建立應用時須要先進入項目目錄。
-
應用目錄以下:
-
__init__.py: 說明目錄是一個Python模塊。
-
models.py: 寫和數據庫項目的內容, 設計模型類。
-
views.py: 接收請求,進行處理,與M和T進行交互,返回應答。定義處理函數,視圖函數。
- 定義處理函數,視圖函數---相對於mini-web中的處理函數 def def add_focus(ret): # 1. 獲取股票代碼
-
tests.py: 寫測試代碼的文件。
-
admin.py: 網站後臺管理相關的文件。
##5.3 應用註冊 創建應用和項目之間的聯繫,須要對應用進行註冊,修改settings.py中的INSTALLED_APPS配置項。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'booktest' #加入'booktest', # 進行應用的註冊 ]
##5.4 啓動項目
- 運行開發web服務器命令:python manage.py runserver
- 使用Django中內置的服務器:python manage.py runserver
- 複製文件中的http://127.0.0.1:8000/到瀏覽器並打開(或192.168.x.xx:xxxx)
- 若是是虛擬機中,可能出現:主機沒法訪問虛擬機中運行的Django項目
- 運行Django的命令,要寫成: python3 manage.py runserver 0.0.0.0:8000 ,重點就是這個0.0.0.0,這樣才能讓外部訪問到
- 參考連接2
- 若是出現:Invalid HTTP_HOST header: '192.168.1.111:8000'. You may need to add '192.168.1.111' to ALLOWED_HOSTS
- 在咱們建立的項目裏修改setting.py文件 ALLOWED_HOSTS = ['*'] #在這裏請求的host添加了*
- 參考連接3
- 複製文件中的http://127.0.0.1:8000/到瀏覽器並打開(或192.168.x.xx:xxxx)
#6. 模型類 ##6.1 ORM
django中內嵌了ORM框架,ORM框架能夠將類和數據表進行對應起來,只須要經過類和對象就能夠對數據表進行操做。
- 在Django中主要是 設計類:模型類。
- 在models.py文件中填寫 ORM另一個做用:根據設計的類生成數據庫中的表。
##6.2 模型類設計 在應用models.py中設計模型類,必須繼承於models.Model類。
- 1) 設計BookInfo類。
- 2) 設計HeroInfo類。 Models.ForeignKey能夠創建兩個模型類之間一對多的關係,django在生成表的時候,就會在多端的表中建立一列做爲外鍵,創建兩個表之間一對多的關係。
##6.3 模型類生成表
-
- 生成遷移文件
- 命令:python manage.py makemigrations 遷移文件是根據模型類生成的。
-
- 執行遷移生成表
- 命令:python mange.py migrate 根據遷移文件生成表。 生成表名的默認格式: 應用名_模型類名小寫
- 3)安裝sqliteman:sudo apt-get install sqliteman 安裝失敗,更換源
- 根據遷移文件生成表,生成表名的默認格式: 應用名_模型類名小寫
##6.4 經過模型類操做數據表
- 進入項目shell的命令: python manage.py shell 如下爲在相互shell終端中演示的例子:
- 首先導入模型類:
> from booktest.models import BookInfo,HeroInfo #1) 向booktest_bookinfo表中插入一條數據。 b = BookInfo() #定義一個BookInfo類的對象 b.btitle ='天龍八部' #定義b對象的屬性並賦值 b.bpub_date = date(1990,10,11) b.save() #纔會將數據保存進數據庫 #2) 查詢出booktest_bookinfo表中id爲1的數據。 b = BookInfo.objects.get(id=1) #3) 在上一步的基礎上改變b對應圖書的出版日期。 b.bpub_date = date(1989,10,21) b.save() #纔會更新表格中的數據 #4) 緊接上一步,刪除b對應的圖書的數據。 b.delete() #纔會刪除 #5) 向booktest_heroInfo表中插入一條數據。 h = HeroInfo() h.hname = '郭靖' h.hgender = False h.hcomment = ‘降龍十八掌’ b2 = BookInfo.objects.get(id=2) h.hbook = b2 #給關係屬性賦值,英雄對象所屬的圖書對象 h.save() #6) 查詢圖書表裏面的全部內容。 BookInfo.objects.all() HeroInfo.objects.all()
###6.4.1. models.py中:
from django.db import models # 設計和表對應的類,模型類 # Create your models here. # 一類 # 圖書類 class BookInfo(models.Model): # 要繼承models.Model之後,纔是一個模型類 # '''圖書模型類''' # 圖書名稱,Charfield說明是一個字符串,max_length指定字符串的最大長度 btitle = models.CharField(max_length=20) # 出版日期,DateField說明是一個日期類型 bpub_date = models.DateField() # 生成的db.sqlite3能夠用sudo apt-get install sqliteman後,打開 # django默認sqlite小型數據庫,要替換成mysql # 多類 # 英雄人物類 # 英雄名 name # 性別 hgender # 年齡 hage # 備註 hcomment # 關係屬性 hbook,創建圖書類和英雄人物類之間的一對多關係 class HeroInfo(models.Model): # '''英雄人物模型類''' hname = models.CharField(max_length=20) # 英雄名稱 # 性別,BooleanField說明是bool類型,default指定默認值,False表明男 hgender = models.BooleanField(default=False) # 備註 hcomment = models.CharField(max_length=128) # 關係屬性 hbook,創建圖書類和英雄人物類之間的一對多關係 # 關係屬性對應的表的字段名格式: 關係屬性名_id hbook = models.ForeignKey('BookInfo', on_delete=models.CASCADE,) # ForeignKey外鍵 # 經過模型類操做數據表 # 進入項目shell的命令:python manage.py shell # # 增長實例屬性要和類屬性名稱同樣
##6.5 關聯操做
###1) 查詢出id爲2的圖書中全部英雄人物的信息。
b = BookInfo.objects.get(id=2) b.heroinfo_set.all() #查詢出b圖書中全部英雄人物的信息
#7. 後臺管理
##1) 本地化
- 語言和時區的本地化。
- 修改settings.py文件。
# LANGUAGE_CODE = 'en-us' LANGUAGE_CODE = 'zh-hans' # 使用中文 # TIME_ZONE = 'UTC' TIME_ZONE = 'Asia/Shanghai' # 中國時間
##2) 建立管理員
- 命令:python manage.py createsuperuser
- 執行時,可能會報錯:Django項目出現: 禁止訪問(403),CSRF驗證失敗,相應中斷
- 解決辦法:在app的views.py 文件中能夠添加一個 from django.template import RequestContext 而後,渲染函數render 添加便可。
- 如: return render(request, ‘users/register.html’,context={‘form’:form})
- 參考連接7.2
##3) 註冊模型類 在應用下的admin.py中註冊模型類,告訴djang框架根據註冊的模型類來生成對應表管理頁面。
from booktest.models import BookInfo, HeroInfo admin.site.register(BookInfo) admin.site.register(HeroInfo)
- __str__:若是一個類中定義了__str__方法,那麼在打印對象時,默認輸出該方法的返回值
- models.py中:重寫一個__str__方法
class BookInfo(models.Model): """圖書模型類""" ... def \_\_str__(self): # 返回英雄名 return self.hname
##4) 自定義管理頁面 自定義模型管理類:模型管理類就是告訴django在生成的管理頁面上顯示哪些內容。
class BookInfoAdmin(admin.ModelAdmin): """圖書模型管理類""" list_display = ['id', 'btitle', 'bpub_date'] class HeroInfoAdmin(admin.ModelAdmin): """英雄人物管理類""" list_display = ['id', 'hname', 'hcomment'] # 註冊模型類 admin.site.register(BookInfo, BookInfoAdmin) admin.site.register(HeroInfo, HeroInfoAdmin)
#8. 視圖 在Django中,經過瀏覽器去請求一個頁面時,使用視圖函數來處理這個請求的,視圖函數處理以後,要給瀏覽器返回頁面內容。 ##8.1視圖函數的使用 ###1) 定義視圖函數 視圖函數定義在views.py中。
- 例:
def index(request): #進行處理。。。 return HttpResponse('hello python')
視圖函數必須有一個參數request,進行處理以後,須要返回一個HttpResponse的類對象,hello python就是返回給瀏覽器顯示的內容。 ###2) 進行url配置---項目文件夾(test1)下的urls.py url配置的目的是讓創建url和視圖函數的對應關係。url配置項定義在urlpatterns的列表中,每個配置項都調用url函數。 url函數有兩個參數,第一個參數是一個正則表達式,第二個是對應的處理動做。
- 配置url時,有兩種語法格式:
- a) url(正則表達式,視圖函數名)
- b) url(正則表達式,include(應用中的urls文件))
- 工做中在配置url時,首先在項目的urls.py文件中添加配置項,
- 但並不寫具體的url和視圖函數之間的對應關係,而是寫包含具體應用的urls.py文件,
- 而後,在應用的urls.py文件中寫url和視圖函數的對應關係。 ##8.2 url匹配的過程 在項目的/test1/urls.py文件中包含具體應用的urls.py文件,應用的/booktest/urls.py文件中寫url和視圖函數的對應關係。
urlpatterns = [ url(r'^admin/', admin.site.urls), # 配置項目 url(r'^',include('booktest.urls')), # 包含booktest應用中urls # path('admin/', admin.site.urls), ]
- 可能會報錯:include()函數報錯'provide the namespace argument to include() instead.' % len(arg)
- 解決方案:url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')),
- 參考連接8.2
# 建議直接將項目test1/urls.py文件的內容,直接複製到應用booktest/urls.py文件中,再將不須要的地方修改掉,這樣就不會錯了。 """test/urls.py""" from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')), ] # --------------------------------------------------------------------------------- """booktest/urls.py""" from django.conf.urls import url from booktest import views # 建立列表urlpatterns,視圖調用就是從這個列表中調用, # 須要經過導入from django.conf.urls import url 來調用項目的urls文件 # 在應用的urls文件中進行url配置的時候: # 1.嚴格匹配開頭和結尾 urlpatterns = [ # 經過url函數設置url路由配置項 url(r'^index$', views.index), # 寫入對應的index名字,創建/index和視圖index之間的關係 # url(r'^index2', views.index2), # 此時的輸入仍是「老鐵,沒毛病」不對,由於在上一項匹配成功後,就再也不匹配下一項了 url(r'^index2$', views.index2), # 故,爲了解決這個問題,需嚴格匹配開頭和結尾,加上^與$ url(r'^books$', views.show_books), # 顯示圖書信息,即/boos頁面顯示的內容 url(r'^books/(\d+)$', views.detail), # 顯示英雄信息,報錯,須要一個bid的位置參數,這時要將\d+做爲一個組() ]
8.2.1. 當用戶輸入如http://127.0.0.1:8000/aindex時,去除域名和最前面的/,剩下aindex,拿aindex字符串
8.2.2. 先到項目的urls文件中進行匹配,配置成功後,去除匹配的a字符,拿剩下的index字符串繼續到項目的urls
8.2.3. 文件中進行正則匹配,匹配成功以後執行視圖函數index,index視圖函數返回內容hello python給瀏覽器顯示
#9. 模板 模板不只僅是一個html文件。 ##9.1 模板文件的使用
- 1 建立模板文件夾:項目test1/下面建立templates文件夾---/test1/templates/
- 2 配置模板目錄
- settings.py文件中有TEMPLATES 選項,這個配置就是讓咱們去設置模板目錄的。
- 在'DIRS': []中設置模板文件的目錄,設置路徑,可是路徑不能隨便設置,而應該根據BASE_DIR來設置
- 項目目錄的絕對路徑,pwd,/home/huang/bj18/test1獲得的就是項目目錄
- 設置時,將BASE_DIR和模板目錄進行拼接
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], # 設置模板文件目錄,路徑 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
-
設置完模板目錄後,便可使用,爲了給多個應用(booktest等)使用,不混淆,會在模板文件夾(templates)下,再新建同名文件夾booktest,
-
新建模板文件index.html,寫好內容後,便可使用模板文件;
-
在mini_frame框架中,手動打開一個文件讀取出來,Django中不能這樣作,使用模板文件應該遵循如下步驟:
-
3 使用模板文件
- 1.定義視圖函數,HttpRequest
- 在booktest下新建一個urls.py
- 視圖函數的做用是: 調用模板,處理數據並返回給瀏覽器。
- 若是須要操做數據庫,須要和M、T進行交互
- 2.進行url配置,創建url地址和視圖的對應關係,和Flask類似
- 瀏覽器中輸入http:127.0.0.1:8000/index # 用戶要顯示該url,須要在應用app中的urls列表中,添加該url
- 1.定義視圖函數,HttpRequest
from django.shortcuts import render from django.http import HttpResponse from django.template import loader, RequestContext from booktest.models import BookInfo, HeroInfo # 導入模型類 def index(request): ··· return render(request, 'booktest/index.html', {'content': 'hello world', 'list':list(range(1, 10))}, )
urlpatterns = [ url(r'^index$', views.index), # 寫入對應的index名字,創建/index和視圖index之間的關係 ]
如下a)-c)爲視圖函數調用模板文件的分析過程,可省略: - 發現除get_template('booktest/index.html')中的'booktest/index.html'、context中的字典不一樣外,其他的部分都相同, - 故,從新定義一個函數my_render(),但此方法是多餘的,由於已經導入了render,因此能夠直接使用 ``` def my_render(request, template_path, context_dict): """使用模板文件""" # 直接將index中的模板文件拿過來使用 # 1.加載模板文件 temp = loader.get_template(template_path) # 寫上目錄,該目錄是相對templetes的目錄---改成template_path # 2.定義模板文件上下文:給模板文件傳遞數據,request,和要傳遞的數據,經過{}的鍵值對來傳減去 # 導入from django.template import loader, RequestContext # context = RequestContext(request, {''}) # Django1.11之後,就是直接傳入{}便可,再也不傳入RequestContext(request, {''})---{}字典也改成經過context_dict來改變 # context = {} context = context_dict # 3.模板渲染(目的是把使用的變量,還有一些語句給替換掉):產生標準的html內容,temp中有一個render方法,將context放進去 res_html = temp.render(context) # 4.返回給瀏覽器 return HttpResponse(res_html) ``` - a)加載模板文件----views.py中,使用模板文件 # 1.加載模板文件 - 導入包 from django.template import loader - temp = loader.get_template('booktest/index.html') # 寫上目錄,該目錄是相對templetes的目錄 - b) 定義目標上下文---給模板文件傳遞定義的變量的值 - 給**模板文件傳遞數據**:request和要傳遞的數據,經過{}的鍵值對來傳進去 - 導入from django.template import loader, RequestContext - context = RequestContext(request, {''}) # Django1.11之後,就是直接傳入{}便可,再也不傳入RequestContext(request, {''}) - \# context = {} - c) 模板渲染(目的是把使用的變量,還有一些語句給替換掉):產生標準的html內容,temp中有一個render方法,將context放進去 - res_html = temp.render(context) - d) 返回給瀏覽器 - return HttpResponse(res_html)
9.2 給模板文件傳遞數據
- 模板變量使用:{{ 模板變量名 }}
- 模板代碼段:{%代碼段%}
- for循環:
{% for i in list %} list不爲空時執行的邏輯 {% empty %} list爲空時執行的邏輯 {% endfor %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模板文件</title> <style type="text/css"> </style> </head> <body> <h1>這是一個模板文件</h1> 使用模板變量:<br/> {{ content }}<br/> 使用列表:<br/> {{ list }}<br/> # 這是直接顯示列表的內容,py中還能夠遍歷出列表中的每個文件 for循環:<br/> <ul> {% for i in list %} <li>{{ i }}</li> {% endfor %} </ul> </body> </html>
#9.3:小結:
- 咱們須要作的事情:
- 1)定義視圖函數
- 視圖函數定義在views.py中。
- 2)進行url配置,項目視圖+應用視圖,兩個。
- """test/urls.py"""
- """booktest/urls.py"""
- 1)定義視圖函數
#10. 案例完成 編碼以前的準備工做:
-
1 設計出訪問頁面的url和對應的視圖函數的名字,肯定視圖函數的功能。
- def show_books()、detail()
-
2 設計模板文件的名字。
- area.html、index.html
如下爲案例中的簡單設計過程:
-
1 完成圖書信息的展現:
- 1.1 設計url,經過瀏覽器訪問 http://127.0.0.1:8000/books 時顯示圖書信息頁面。
# /test1/urls.py: urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^', include(('booktest.urls', 'booktest'), namespace='booktest')), ]
#/booktest/urls.py: urlpatterns = [ # 經過url函數設置url路由配置項 url(r'^index$', views.index), url(r'^books$', views.show_books), # 顯示圖書信息,即/books頁面顯示的內容 url(r'^books/(\d+)$', views.detail), # 顯示英雄信息,報錯,須要一個bid的位置參數,這時要將\d+做爲一個組() ]
- 1.1 設計url,經過瀏覽器訪問 http://127.0.0.1:8000/books 時顯示圖書信息頁面。
-
1.2 設計url對應的視圖函數show_books。
- 查詢出全部圖書的信息,將這些信息傳遞給模板文件。
# views.py: import sys from django.shortcuts import render from django.http import HttpResponse from django.template import loader, from booktest.models import BookInfo, HeroInfo # 導入模型類 def show_books(request): """顯示圖書的信息""" # 1. 經過M查找圖書表中的數據 books = BookInfo.objects.all() # 2. 使用模板 return render(request, 'booktest/show_books.html', {'books': books})
- 查詢出全部圖書的信息,將這些信息傳遞給模板文件。
-
1.3 編寫模板文件show_books.html。
- 遍歷顯示出每一本圖書的信息。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>顯示圖書信息</title> <style type="text/css"> </style> </head> <body> 圖書信息以下: {% for book in books %} <li><a href="/books/{{ book.id }}">{{ book.btitle}}</a></li> {% endfor %} </body> </html>
- 2 完成點擊某本圖書時,顯示出圖書裏全部英雄信息的頁面。
- 2.1 設計url,經過訪問http://127.0.0.1:8000/books/數字時顯示對應的英雄信息頁面。
- 這裏數字指點擊的圖書的id。
url(r'^books/(\d+)$', views.detail), # 顯示英雄信息,報錯,須要一個bid的位置參數,這時要將\d+做爲一個組()
- 這裏數字指點擊的圖書的id。
- 2.2 設計對應的視圖函數detail。
- 接收圖書的id,根據id查詢出相應的圖書信息,而後查詢出圖書中的全部英雄信息。
def detail(request, bid): '''查詢圖書關聯英雄信息''' # 1. 根據bid查詢圖書信息 book = BookInfo.objects.get(id=bid) # 2. 查詢和book關聯的信息---要分析1對多(由1查多b.heroinfo_set.all())仍是多對1(h.hbook) # HeroInfo.objects.fliter(hbook__id=1) heros = book.heroinfo_set.all() # 須要顯示圖書的名字,和關聯的英雄名字和備註 # 3. 使用模板detail,建立templates/bootest/detail.html return render(request, 'booktest/detail.html', {'book': book, 'heros': heros}) # 注意,此處是heros,不是hero,否則圖書信息就沒法顯示 # 去應用booktest/urls中設置地址。
- 接收圖書的id,根據id查詢出相應的圖書信息,而後查詢出圖書中的全部英雄信息。
- 2.3 編寫模板文件detail.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>顯示圖書關聯的英雄信息</title> <style type="text/css"> </style> </head> <body> <h1>{{ book.btitle }}</h1> 英雄信息以下:<br/> <ul> {% for hero in heros %} <li>{{ hero.hname }}--{{ hero.hcomment }}</li> {% empty %} <li>沒有英雄信息</li> {% endfor %} </ul> </body> </html>
- 2.1 設計url,經過訪問http://127.0.0.1:8000/books/數字時顯示對應的英雄信息頁面。