Django的簡單使用

Django 基礎簡介

基礎簡介

1. 軟件框架

一個公司是由公司中的各部部門來組成的,每一個部門擁有特定的職能,部門與部門之間通過相互的配合來完成讓公司運轉起來。

一個軟件框架是由其中各個軟件模塊組成的,每一個模塊都有特定的功能,模塊與模塊之間通過相互配合來完成軟件的開發。

軟件框架是針對某一類軟件設計問題而產生的。

2. MVC框架

2.1 MVC簡介

MVC最初是由施樂公司旗下的帕羅奧多研究中心中的一位研究人員給 smalltalk語言發明的一中軟件設計模式。

MVC的產生理念: 分工。讓專門的人去做專門的事。

MVC的核心思想: 解耦

MVC的思想被應用在的web開發的方面,產生了web MVC框架

2.2 Web MVC框架模塊功能

通過瀏覽器註冊用戶信息。

image.png

M:Model,模型, 和數據庫進行交互。

V:View,視圖, 產生html頁面。

C:Controller,控制器, 接收請求,進行處理,與M和V進行交互,返回應答。

3. Django框架

3.1 簡介

Django是勞倫斯出版集團的開發人員為開發新聞內容網站而設計出來的一個軟件,它遵循MVC思想,但是有自己的一個名詞,叫做MVT

Django遵循快速開發和DRY原則。Do not repeat yourself.不要自己去重複一些工作。

3.2 MVT各部分功能

image.png

M:Model,模型, 和MVC中M功能相同,和數據庫進行交互。

V:View,視圖, 和MVC中C功能相同,接收請求,進行處理,與M和T進行交互,返回應答。

T:Template,模板, 和MVC中V功能相同,產生html頁面。

4. 虛擬環境

4.1 概念

image.png

之前安裝python包的命令: sudo pip3 install 包名

包的安裝路徑:/usr/local/lib/python3.5/dist-packages

在同一個python環境中安裝同一個包的不同版本,後安裝的包會把原來安裝的包覆蓋掉。這樣,如果同一台機器上兩個項目依賴於相同包的不同版本,則會導致一些項目運行失敗。

解決的方案就是:虛擬環境。

虛擬環境是真實python環境的複製版本。

在虛擬環境中使用的python是複製的python,安裝python包也是安裝在複製的python中。

4.2 安裝和配置

安裝虛擬環境的命令:

1)sudo pip install virtualenv -i [//pypi.tuna.tsinghua.edu.cn/simple/](//pypi.tuna.tsinghua.edu.cn/simple/) #安裝虛擬環境

2)sudo pip install virtualenvwrapper -i [//pypi.tuna.tsinghua.edu.cn/simple/](//pypi.tuna.tsinghua.edu.cn/simple/) #安裝虛擬環境擴展包

3)編輯家目錄下面的.bashrc文件,添加下面兩行。

export WORKON_HOME=$HOME/.virtualenvs
export VIRTUALENVWRAPPER_PYTHON='/usr/bin/python3'
# export VIRTUALENVWRAPPER_VIRTUALENV=~/virtualenvs
export VIRTUALENVWRAPPER_VIRTUALENV=~/.local/bin/virtualenv
source /usr/local/bin/virtualenvwrapper.sh

4)使用source .bashrc使其生效一下。

4.3 使用

創建虛擬環境命令:

mkvirtualenv 虛擬環境名

創建python3虛擬環境:

mkvirtualenv -p python3 bj11_py3

進入虛擬環境工作:

workon 虛擬環境名

查看機器上有多少個虛擬環境:

workon 空格 + 兩個tab鍵

退出虛擬環境:

deactivate

刪除虛擬環境:

rmvirtualenv 虛擬環境名

虛擬環境下安裝包的命令:

pip install 包名

注意:不能使用sudo pip install 包名,這個命令會把包安裝到真實的主機環境上而不是安裝到虛擬環境中。

查看虛擬環境中安裝了哪些python包:

pip list
pip freeze

安裝django環境:

pip install django==3.2.6

拓展:

apt-get install 軟件

pip install python包名

5. 項目創建

5.1 創建Django項目

命令:

django-admin startproject 項目名

注意:創建應用必須先進入虛擬環境。

項目目錄如下:

image.png

5.2 創建Django應用

image.png

一個項目由很多個應用組成的,每一個應用完成一個功能模塊。

創建應用的命令如下:

python manage.py startapp 應用名

注意:創建應用時需要先進入項目目錄。

應用目錄如下:

image.png

5.3 應用註冊

建立應用和項目之間的聯繫,需要對應用進行註冊。

修改settings.py中的INSTALLED_APPS配置項。

5.4 啟動項目

運行開發web服務器命令:

python manage.py runserver

6. 模型類

6.1 ORM

image.png

django中內嵌了ORM框架,ORM框架可以將類和數據表進行對應起來,只需要通過類和對象就可以對數據表進行操作。

在Django中主要是設計類:模型類。

ORM另外一個作用:根據設計的類生成數據庫中的表。

6.2 模型類設計

在應用models.py中設計模型類。

必須繼承與models.Model類。

  1. 設計BookInfo類。
  2. 設計HeroInfo類。

Models.ForeignKey可以建立兩個模型類之間一對多的關係,django在生成表的時候,就會在多端的表中創建一列作為外鍵,建立兩個表之間一對多的關係。

6.3 模型類生成表

  1. 生成遷移文件
    命令:python manage.py makemigrations
    image.png
    遷移文件是根據模型類生成的。
  2. 行遷移生成表
    命令:python mange.py migrate
    根據遷移文件生成表。
    生成表名的默認格式:
    應用名_模型類名小寫

6.4 通過模型類操作數據表

進入項目shell的命令:

python manage.py shell

以下為在相互shell終端中演示的例子:

首先導入模型類:

from booktest.models import BookInfo,HeroInfo

  1. oktest_bookinfo表中插入一條數據。
b = BookInfo() #定義一個BookInfo類的對象
b.btitle ='天龍八部' #定義b對象的屬性並賦值
b.bpub_date = date(1990,10,11)
b.save() #才會將數據保存進數據庫
  1. booktest_bookinfo表中id為1的數據。
b = BookInfo.objects.get(id=1)
  1. 步的基礎上改變b對應圖書的出版日期。
b.bpub_date = date(1989,10,21)
b.save() #才會更新表格中的數據
  1. 一步,刪除b對應的圖書的數據。
b.delete() #才會刪除
  1. oktest_heroInfo表中插入一條數據。
h = HeroInfo()
h.hname = '郭靖'
h.hgender = False
h.hcomment = '降龍十八掌'
b2 = BookInfo.objects.get(id=2)
h.hbook = b2 #給關係屬性賦值,英雄對象所屬的圖書對象
h.save()
  1. 書表裏面的所有內容。
BookInfo.objects.all()
HeroInfo.objects.all()

6.5 關聯操作

image.png

  1. 查詢出id為2的圖書中所有英雄人物的信息。
b = BookInfo.objects.get(id=2)
b.heroinfo_set.all() #查詢出b圖書中所有英雄人物的信息

7. 後台管理

  1. 本地化

語言和時區的本地化。

修改settings.py文件。

  1. 創建管理員

命令:python manage.py createsuperuser

  1. 註冊模型類

在應用下的admin.py中註冊模型類。

告訴djang框架根據註冊的模型類來生成對應表管理頁面。

b = BookInfo()
str(b) __str__
  1. 自定義管理頁面

自定義模型管理類。模型管理類就是告訴django在生成的管理頁面上顯示哪些內容。

8. 視圖

在Django中,通過瀏覽器去請求一個頁面時,使用視圖函數來處理這個請求的,視圖函數處理之後,要給瀏覽器返回頁面內容。

8.1 視圖函數的使用

  1. 定義視圖函數

視圖函數定義在views.py中。

例:

def index(request):
#進行處理...
        return HttpResponse('hello python')

視圖函數必須有一個參數request,進行處理之後,需要返回一個HttpResponse的類對象,hello python就是返回給瀏覽器顯示的內容。

  1. 進行url配置

url配置的目的是讓建立url和視圖函數的對應關係。url配置項定義在urlpatterns的列表中,每一個配置項都調用url函數。

url函數有兩個參數,第一個參數是一個正則表達式,第二個是對應的處理動作。

配置url時,有兩種語法格式:

  • url(正則表達式,視圖函數名)
  • url(正則表達式,include(應用中的urls文件))

工作中在配置url時,首先在項目的urls.py文件中添加配置項時,並不寫具體的url和視圖函數之間的對應關係,而是包含具體應用的urls.py文件,在應用的urls.py文件中寫url和視圖函數的對應關係。

8.2 url匹配的過程

在項目的urls.py文件中包含具體應用的urls.py文件,應用的urls.py文件中寫url和視圖函數的對應關係。

image.png

當用戶輸入如//127.0.0.1:8000/aindex時,去除域名和最前面的/,剩下aindex,拿aindex字符串到項目的urls文件中進行匹配,配置成功之後,去除匹配的a字符,那剩下的index字符串繼續到應用的urls文件中進行正則匹配,匹配成功之後執行視圖函數index,index視圖函數返回內容hellopython給瀏覽器來顯示。

9. 模板

模板不僅僅是一個html文件。

9.1 模板文件的使用

  1. 創建模板文件夾
  2. 配置模板目錄

image.png

  1. 使用模板文件
    • 加載模板文件
      • 去模板目錄下面獲取html文件的內容,得到一個模板對象。
    • 定義模板上下文
      • 向模板文件傳遞數據。
    • 模板渲染
      • 得到一個標準的html內容。

9.2 給模板文件傳遞數據

10. 案例完成

編碼之前的準備工作:

  1. 設計出訪問頁面的url和對應的視圖函數的名字,確定視圖函數的功能。
  2. 設計模板文件的名字。

以下為案例中的簡單設計過程:

  1. 完成圖書信息的展示:
  2. 設計url,通過瀏覽器訪問 //127.0.0.1:8000/books 時顯示圖書信息頁面
  3. 設計url對應的視圖函數show_books。
    查詢出所有圖書的信息,將這些信息傳遞給模板文件。
  4. 編寫模板文件show_books.html。
    遍歷顯示出每一本圖書的信息。
  5. 完成點擊某本圖書時,顯示出圖書里所有英雄信息的頁面。
  6. 設計url,通過訪問//127.0.0.1:8000/books/數字時顯示對應的英雄信息頁面。
    這裡數字指點擊的圖書的id。
  7. 設計對應的視圖函數detail。
    接收圖書的id,根據id查詢出相應的圖書信息,然後查詢出圖書中的所有英雄信息。
  8. 編寫模板文件detail.html。

Django 模型

模型

1. Django ORM

image.png

O(objects):類和對象。

R(Relation):關係,關係數據庫中的表格。

M(Mapping):映射。

Django ORM框架的功能:

  1. 建立模型類和表之間的對應關係,允許我們通過面向對象的方式來操作數據庫。
  2. 根據設計的模型類生成數據庫中的表格。
  3. 通過方便的配置就可以進行數據庫的切換。

2. Django數據庫配置

2.1 mysql命令回顧

2.2 Django配置使用mysql數據庫

修改settings.py中的DATABASES。

image.png
注意:django框架不會自動幫我們生成mysql數據庫,所以我們需要自己去創建。

2.3 切換mysql數據庫之後不能啟動服務器

需要安裝操作mysql數據庫的包,python2環境和python3環境有以下區別。

  • python2需要安裝mysql-python:

pip install mysql-python

  • python3需要安裝pymysql:

pip install pymysql

python3中安裝好pymysql,需要在test2/init.py中加如下內容:

3. 複習案例

image.png

頁面重定向:服務器不返回頁面,而是告訴瀏覽器再去請求其他的url地址。

  1. 設計模型類並生成表
  2. 設計BookInfo,增加屬性bread和bcomment,另外設置軟刪除標記屬性isDelete。
  3. 設計HeroInfo類,增加軟刪除標記屬性isDelete。
    軟刪除標記:刪除數據時不做真正的刪除,而是把標記數據設置為1表示刪除,目的是防止重要的數據丟失。
  4. 編寫視圖函數並配置URL。
  5. 創建模板文件。
    拆解功能:
  6. 圖書信息展示頁。
  7. 設計url,通過瀏覽器訪問 //127.0.0.1:8000/index時顯示圖書信息頁面
  8. 設計url對應的視圖函數index。
    查詢出所有圖書的信息,將這些信息傳遞給模板文件。
  9. 編寫模板文件index.html。

遍歷顯示出每一本圖書的信息並增加新建和刪除超鏈接。

  1. 圖書信息新增。
    a. 設計url,通過瀏覽器訪問 //127.0.0.1:8000/create時向數據庫中新增一條圖書信息
    b. 設計url對應得視圖函數create。
  2. 圖書信息刪除。
    a. 設計url,通過瀏覽器訪問 //127.0.0.1:8000/delete數 字刪除數據庫中對應的一條圖書數據
    其中數字是點擊的圖書的id。
    b. 設計url對應的視圖函數delete。 獲取圖書的id,進行刪除。

4. 字段屬性和選項

4.1 模型類屬性命名限制

  1. 不能是python的保留關鍵字。
  2. 不允許使用連續的下劃線,這是由django的查詢方式決定的。
  3. 定義屬性時需要指定字段類型,通過字段類型的參數指定選項,語法如下:

屬性名=models.字段類型(選項)

4.2 字段類型

使用時需要引入django.db.models包,字段類型如下:

4.3 字段選項

通過選項實現對字段的約束,選項如下:

對比:null是數據庫範疇的概念,blank是後台管理頁面表單驗證範疇的。

經驗:

當修改模型類之後,如果添加的選項不影響表的結構,則不需要重新做遷移,商品的選項中default和blank不影響表結構。

參考文檔:

//python.usyiyi.cn/translate/django_182/index.html

5. 查詢

5.1 mysql的日誌文件

mysql.log是mysql的日誌文件,裏面記錄的對MySQL數據庫的操作記錄。默認情況下mysql的日誌文件沒有產生,需要修改mysql的配置文件,步驟如下:

  1. 使用下面的命令打開mysql的配置文件,去除68,69行的注釋,然後保存。

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

  1. 重啟mysql服務,就會產生mysql日誌文件。

sudo service mysql restart

  1. 打開MySQL的日誌文件。

/var/log/mysql/mysql.log 是mysql日誌文件所在的位置。

使用下面的命令可以實時查看mysql的日誌文件:

sudo tail -f /var/log/mysql/mysql.log

5.2 查詢函數

通過模型類.objects屬性可以調用如下函數,實現對模型類對應的數據表的查詢。

get示例

例:查詢圖書id為3的圖書信息。

all方法示例:

例:查詢圖書所有信息。

filter方法示例:

條件格式:

模型類屬性名__條件名=值

查詢圖書評論量為34的圖書的信息:

a) 判等 條件名:exact

例:查詢編號為1的圖書。
# Django models 語法
BookInfo.objects.get(id=1)

b) 模糊查詢

例:查詢書名包含』傳』的圖書。contains

BookInfo.objects.filter(btitle__contains='傳')

例:查詢書名以』部』結尾的圖書 endswith 開頭:startswith

BookInfo.objects.filter(btitle__endswith='部')

c)空查詢 isnull

例:查詢書名不為空的圖書。isnull
select * from booktest_bookinfo where btitle is not null;
# Django models 語法
BookInfo.objects.filter(btitle__isnull=False)

d)範圍查詢 in

例:查詢id為1或3或5的圖書。
select * from booktest_bookinfo where id in (1,3,5);
# Django models 語法
BookInfo.objects.filter(id__in = [1,3,5])

e)比較查詢 gt(greate than) lt(less than) gte(equal) 大於等於

lte 小於等於

例:查詢id大於3的圖書。
Select * from booktest_bookinfo where id>3;
# Django models 語法
BookInfo.objects.filter(id__gt=3)

f)日期查詢

# 例:查詢1980年發表的圖書。
BookInfo.objects.filter(bpub_date__year=1980)
# 例:查詢1980年1月1日後發表的圖書。
from datetime import date
BookInfo.objects.filter(bpub_date__gt=date(1980,1,1))

exclude方法示例:

# 例:查詢id不為3的圖書信息。
BookInfo.objects.exclude(id=3)

order_by方法示例:

作用:進行查詢結果進行排序。

# 例:查詢所有圖書的信息,按照id從小到大進行排序。
BookInfo.objects.all().order_by('id')
# 例:查詢所有圖書的信息,按照id從大到小進行排序。
BookInfo.objects.all().order_by('-id')
# 例:把id大於3的圖書信息按閱讀量從大到小排序顯示。
BookInfo.objects.filter(id__gt=3).order_by('-bread')

6. F對象

作用:用於類屬性之間的比較。

使用之前需要先導入

from django.db.models import F
# 例:查詢圖書閱讀量大於評論量圖書信息。
BookInfo.objects.filter(bread__gt=F('bcomment'))
# 例:查詢圖書閱讀量大於2倍評論量圖書信息。
BookInfo.objects.filter(bread__gt=F('bcomment')*2)

7. Q對象

作用:用於查詢時條件之間的邏輯關係。not and or,可以對Q對象進行&|~操作。

使用之前需要先導入:

from django.db.models import Q
# 例:查詢id大於3且閱讀量大於30的圖書的信息。
BookInfo.objects.filter(id__gt=3, bread__gt=30)
BookInfo.objects.filter(Q(id__gt=3)&Q(bread__gt=30))
# 例:查詢id大於3或者閱讀量大於30的圖書的信息。
BookInfo.objects.filter(Q(id__gt=3)|Q(bread__gt=30))
# 例:查詢id不等於3圖書的信息。
BookInfo.objects.filter(~Q(id=3))

8. 聚合函數

作用:對查詢結果進行聚合操作。

sum count avg max min

aggregate:調用這個函數來使用聚合。 返回值是一個字典

使用前需先導入聚合類:

from django.db.models import Sum,Count,Max,Min,Avg
# 例:查詢所有圖書的數目。
BookInfo.objects.all().aggregate(Count('id'))

{'id__count': 5}
# 例:查詢所有圖書閱讀量的總和。
BookInfo.objects.aggregate(Sum('bread'))
{'bread__sum': 126}

count函數 返回值是一個數字

作用:統計滿足條件數據的數目。

# 例:統計所有圖書的數目。
BookInfo.objects.all().count()
BookInfo.objects.count()
# 例:統計id大於3的所有圖書的數目。
BookInfo.objects.filter(id__gt=3).count()

小結:

查詢相關函數
get :返回一條且只能有一條數據,返回值是一個對象,參數可以寫查詢條件。

all :返回模型類對應表的所有數據,返回值是 Oueryset 。

filter :返回滿足條件的數據,返回值是 Oueryset ,參數可以寫查詢條件。

exclude :返回不滿足條件的數據,返回值是 Oueryset ,參數可以寫查詢條件。

order _ by :對查詢結果進行排序,返回值是 Queryset ,參數中寫排序的字段。

注意:

  1. get,filter , exclude 函數中可以寫查詢條件,如果傳多個參數,條件之間代表且的關係。
  2. all,filter , exclude , order _ by 函數的返回值是 Queryset 類的實例對象, 叫做查詢集.

from django.db.models import F,Q,Sum,Count,Avg,Max,Min

F對象:用於類屬性之間的比較。
Q對象:用於條件之間的邏輯關係。

aggregate :進行聚合操作,返回值是一個字典,進行聚合的時候需要先導入聚合類。
count :返回結果集中數據的數目,返回值是一個數字。

注意:對一個 Oueryset 實例對象,可以繼續調用上面的所有函數。

參考文檔:

//python.usyiyi.cn/translate/django_182/ref/models/querysets.html

9. 查詢集

all, filter, exclude, order_by調用這些函數會產生一個查詢集,QuerySet類對象可以繼續調用上面的所有函數。

9.1 查詢集特性

  1. 惰性查詢:只有在實際使用查詢集中的數據的時候才會發生對數據庫的真正查詢。
  2. 緩存:當使用的是同一個查詢集時,第一次使用的時候會發生實際數據庫的查詢,然後把結果緩存起來,之後再使用這個查詢集時,使用的是緩存中的結果。

9.2 限制查詢集

可以對一個查詢集進行取下標或者切片操作來限制查詢集的結果。

對一個查詢集進行切片操作會產生一個新的查詢集,下標不允許為負數。

取出查詢集第一條數據的兩種方式:

exists:判斷一個查詢集中是否有數據。True False

10. 模型類關係

  1. 一對多關係

例:圖書類-英雄類

models.ForeignKey() 定義在多的類中。

  1. 多對多關係

例:新聞類-新聞類型類 體育新聞 國際新聞

models.ManyToManyField() 定義在哪個類中都可以。

  1. 一對一關係

例:員工基本信息類-員工詳細信息類. 員工工號

models.OneToOneField定義在哪個類中都可以。

11. 關聯查詢(一對多)

11.1 查詢和對象關聯的數據

在一對多關係中,一對應的類我們把它叫做一類,多對應的那個類我們把它叫做多類,我們把多類中定義的建立關聯的類屬性叫做關聯屬性。

# 例:查詢id為1的圖書關聯的英雄的信息。
b=BookInfo.objects.get(id=1)
b.heroinfo_set.all()

通過模型類查詢:

HeroInfo.objects.filter(hbook__id=1)
# 例:查詢id為1的英雄關聯的圖書信息。
h = HeroInfo.objects.get(id=1)
h.hbook

通過模型類查詢:

BookInfo.objects.filter(heroinfo__id=1)

格式:
image.png

由一類的對象查詢多類的時候:

一類的對象.多類名小寫_set.all() #查詢所用數據

由多類的對象查詢一類的時候:

多類的對象.關聯屬性 #查詢多類的對象對應的一類的對象

由多類的對象查詢一類對象的id時候:

多類的對象. 關聯屬性_id

11.2 通過模型類實現關聯查詢

image.png

例:查詢圖書信息,要求圖書關聯的英雄的描述包含』八』。

BookInfo.objects.filter(heroinfo__hcomment__contains='八')

例:查詢圖書信息,要求圖書中的英雄的id大於3.

BookInfo.objects.filter(heroinfo__id__gt=3)

例:查詢書名為「天龍八部」的所有英雄。

HeroInfo.objects.filter(hbook__btitle='天龍八部')

通過多類的條件查詢一類的數據:

一類名.objects.filter(多類名小寫__多類屬性名__條件名)

通過一類的條件查詢多類的數據:

多類名.objects.filter(關聯屬性__一類屬性名__條件名)

12. 入、更新和刪除

調用一個模型類對象的save方法的時候就可以實現對模型類對應數據表的插入和更新。

調用一個模型類對象的delete方法的時候就可以實現對模型類對應數據表數據的刪除。

13. 自關聯

image.png

自關聯是一種特殊的一對多的關係。

案例:顯示廣州市的上級地區和下級地區。

地區表:id, atitle, aParent_id;

mysql終端中批量執行sql語句:

source areas.sql;

14. 管理器

BookInfo.objects.all()->objects是一個什麼東西呢?

答:objects是Django幫我自動生成的管理器對象,通過這個管理器可以實現對數據的查詢。objects是models.Manger類的一個對象。自定義管理器之後Django不再幫我們生成默認的objects管理器。

14.1 自定義模型管理器類

  1. 自定義一個管理器類,這個類繼承models.Manger類。
  2. 再在具體的模型類里定義一個自定義管理器類的對象。

14.2 自定義管理器類的應用場景

  1. 改變查詢的結果集。
    比如調用BookInfo.books.all()返回的是沒有刪除的圖書的數據。
  2. 添加額外的方法。
    管理器類中定義一個方法幫我們操作模型類對應的數據表。
    使用self.model()就可以創建一個跟自定義管理器對應的模型類對象。
    小結:

image.png

15. 元選項

Django默認生成的表名:

應用名小寫_模型類名小寫。

元選項:

需要在模型類中定義一個元類Meta,在裏面定義一個類屬性db_table就可以指定表名。

image.png

Django 視圖

視圖

1. 視圖的功能

接收請求,進行處理,與M和T進行交互,返回應答。

返回html內容 HttpResponse,也可能重定向 redirect,還可以返回json數據。

2. 視圖函數使用

2.1 使用

  1. 定義視圖函數
    request參數必須有。是一個HttpRequest類型的對象。參數名可以變化,
    但不要更改。
  2. 配置url
    建立url和視圖函數之間的對應關係。

3. url配置的過程

  1. 在項目的urls文件中包含具體應用的urls文件,在具體應用的urls文件中包含具體url和視圖的對應關係。
  2. url配置項是定義在一個名叫urlpatterns的列表中,其中的每一個元素就是一個配置項,每一個配置項都調用url函數。

4. url匹配的過程

image.png

url: //127.0.0.1:8000/aindex?a=1

  1. 去除域名和後面的參數,剩下/aindex,再把前面的/去掉,剩下aindex
  2. 拿aindex先到項目的url.py文件中進行從上到下的匹配,匹配成功之後執行後面對應的處理動作,就是把匹配成功的部分a字符去除,然後拿剩下的部分index到應用的urls.py文件中再進行從上到下的匹配。
  3. 如果匹配成功則調用相應的視圖產生內容返回給客戶端。如果匹配失敗則產生404錯誤。

4. 錯誤視圖

404:找不到頁面,關閉調試模式之後,默認會顯示一個標準的錯誤頁面,如果要顯示自定義的頁面,則需要的templates目錄下面自定義一個404.html文件。

  1. url沒有配置
  2. url配置錯誤

500: 服務器端的錯誤。

  1. 視圖出錯

網站開發完成需要關閉調試模式,在settings.py文件中:

DEBUG=False

ALLOWED_HOST=[ 『*』]

5. 捕獲url參數

進行url匹配時,把所需要的捕獲的部分設置成一個正則表達式組,這樣django框架就會自動把匹配成功後相應組的內容作為參數傳遞給視圖函數。

  1. 位置參數
    位置參數,參數名可以隨意指定
  2. 關鍵字參數:在位置參數的基礎上給正則表達式組命名即可。
    ?P<組名>
    關鍵字參數,視圖中參數名必須和正則表達式組名一致.

6. 普通登錄案例

6.1顯示出登錄頁面

  1. 設計url,通過瀏覽器訪問 //127.0.0.1:8000/login 時顯示登錄頁面
  2. 設計url對應的視圖函數login。
  3. 編寫模板文件login.html。

6.2 登錄校驗功能

  1. 設計url,點擊登錄頁的登錄按鈕發起請求 //127.0.0.1:8000/login_check時進行登錄校驗。
  2. 設計url對應的視圖函數login_check。
    接收表單提交過來的數據。
    進行登錄校驗,若用戶名密碼正確則跳轉到登錄成功頁。若失敗在跳轉到登錄頁面。
  3. 登錄成功後跳轉到首頁。

7. Ajax

7.1 基本概念

異步的javascript。在不全部加載某一個頁面部的情況下,對頁面進行局的刷新,ajax請求都在後台。

圖片,css文件,js文件都是靜態文件。

  1. 發起ajax請求:jquery發起
  2. 執行相應的視圖函數,返回json內容
  3. 執行相應的回調函數。通過判斷json內容,進行相應處理。

7.2 Ajax登錄案例

  1. 首先分析出請求地址時需要攜帶的參數。
  2. 視圖函數處理完成之後,所返回的json的格式。

顯示出登錄頁面

  1. 設計url,通過瀏覽器訪問 //127.0.0.1:8000/login_ajax 時顯示登錄頁面
  2. 設計url對應的視圖函數login_ajax。
  3. 編寫模板文件login_ajax.html。
def login_ajax(request):
        returnrender(request,'booktest/login_ajax.html')
  1. 登錄校驗功能
  2. 設計url,點擊登錄頁的登錄按鈕發起請求//127.0.0.1:8000/login_ajax_check 時進行登錄校驗。
  3. 設計url對應的視圖函數login_ajax_check。
    接收post提交過來的數據。
    進行登錄校驗,並返回json內容。 JsonRepsone
    Json格式如下:
{『res』:『1』} #表示登錄成功

{『res』:『0』} #表示登錄失敗

8. 狀態保持

http協議是無狀態的。下一次去訪問一個頁面時並不知道上一次對這個頁面做了什麼。

cookie是由服務器生成,存儲在瀏覽器端的一小段文本信息。

cookie的特點:

  1. 以鍵值對方式進行存儲。
  2. 通過瀏覽器訪問一個網站時,會將瀏覽器存儲的跟網站相關的所有cookie信息發送給該網站的服務器。request.COOKIES
  3. cookie是基於域名安全的。www.baidu.com
  4. cookie是有過期時間的,如果不指定,默認關閉瀏覽器之後cookie就會過期。

記住用戶名案例:

8.2 Session

session存儲在服務器端。

session的特點:

  1. session是以鍵值對進行存儲的。
  2. session依賴於cookie。唯一的標識碼保存在sessionid cookie中。
  3. session也是有過期時間,如果不指定,默認兩周就會過期。

記住用戶登錄狀態案例。

8.3 cookie和session的應用場景

cookie:記住用戶名。安全性要求不高。

session:涉及到安全性要求比較高的數據。銀行卡賬戶,密碼

image.pngimage.pngimage.png

Django 模板

模板

1. 模板的功能

產生html,控制頁面上展示的內容。模板文件不僅僅是一個html文件。

模板文件包含兩部分內容:

  1. 靜態內容:css,js,html。
  2. 動態內容:用於動態去產生一些網頁內容。通過模板語言來產生。

2. 模板文件的使用

通常是在視圖函數中使用模板產生html內容返回給客戶端。

  1. 加載模板文件 loader.get_template
    獲取模板文件的內容,產生一個模板對象。
  2. 定義模板上下文 RequeseContext
    給模板文件傳遞數據。
  3. 模板渲染產生html頁面內容 render
    用傳遞的數據替換相應的變量,產生一個替換後的標準的html內容。

3. 模板文件加載順序

  1. 首先去配置的模板目錄下面去找模板文件。
  2. 去INSTALLED_APPS下面的每個應用的templates去找模板文件,前提是應用中必須有templates文件夾。

4. 模板語言

模板語言簡稱為DTL。(Django Template Language)

4.1 模板變量

模板變量名是由數字,字母,下劃線和點組成的,不能以下劃線開頭。

使用模板變量:{{模板變量名}}

模板變量的解析順序:

例如:{{ book.btitle }}

  1. 首先把book當成一個字典,把btitle當成鍵名,進行取值book[『btitle』]
  2. 把book當成一個對象,把btitle當成屬性,進行取值book.btitle
  3. 把book當成一個對象,把btitle當成對象的方法,進行取值book.btitle
  • 例如:{{book.0}}
    1. 首先把book當成一個字典,把0當成鍵名,進行取值book[0]
    2. 把book當成一個列表,把0當成下標,進行取值book[0]

如果解析失敗,則產生內容時用空字符串填充模板變量。

使用模板變量時,.前面的可能是一個字典,可能是一個對象,還可能是一個列表。

4.2 模板標籤

{% 代碼段 %}
    for循環:
    {% for x in 列表 %}
    # 列表不為空時執行
    {% empty %}
    # 列表為空時執行
    {% endfor %}
可以通過{{ forloop.counter }}得到for循環遍歷到了第幾次。
{% if 條件 %}

{% elif 條件 %}

{% else %}

{% endif %}

關係比較操作符:> < >= <= == !=

注意:進行比較操作時,比較操作符兩邊必須有空格。

邏輯運算:not and or

4.3 過濾器

過濾器用於對模板變量進行操作。

date:改變日期的顯示格式。

length:求長度。字符串,列表.

default:設置模板變量的默認值。

格式:模板變量|過濾器:參數

自定義過濾器。

自定義的過濾器函數,至少有一個參數,最多兩個

參考資料:(模板標籤和內置過濾器)

//python.usyiyi.cn/documents/django_182/ref/templates/builtins.html

4.4 模板注釋

單行注釋:{# 注釋內容 #}

多行注釋:

{% comment %}
注釋內容
{% endcomment %}

5. 模板繼承

模板繼承也是為了重用html頁面內容。
image.png

在父模板里可以定義塊,使用標籤:

{% block 塊名 %}
塊中間可以寫內容,也可以不寫
{% endblock 塊名%}

子模板去繼承父模板之後,可以重寫父模板中的某一塊的內容。

繼承格式:{% extends 父模板文件路徑%}

{% block 塊名 %}

{{ block.super}} #獲取父模板中塊的默認內容

重寫的內容

{% endblock 塊名%}

6. html轉義

編輯商品詳情信息,數據表中保存的是html內容。

在模板上下文中的html標記默認是會被轉義的。

小於號< 轉換為&lt;

大於號> 轉換為&gt;

單引號' 轉換為&#39;

雙引號" 轉換為 &quot;

與符號& 轉換為 &amp;

要關閉模板上下文字符串的轉義:可以使用 {{ 模板變量|safe}}

{% autoescape off %}
模板語言代碼
{% endautoescape %}

模板硬編碼中的字符串默認不會經過轉義,如果需要轉義,那需要手動進行轉義。

7. csrf攻擊

首先做一個登錄頁,讓用戶輸入用戶名和密碼進行登錄,登錄成功之後跳轉的修改密碼頁面。在修改密碼頁面輸入新密碼,點擊確認按鈕完成密碼修改。

登錄頁需要一個模板文件login.html.修改密碼頁面也需要一個模板文件change_pwd.html.

顯示登錄頁的視圖login,驗證登錄的視圖login_check,顯示發帖頁的視圖change_pwd,處理修改密碼的視圖change_pwd_action.

加功能:

用戶登錄之後才可以進行修改密碼操作。

登錄裝飾器函數。

案例流程圖:

django防止csrf的方式:

  1. 默認打開csrf中間件。
  2. 表單post提交數據時加上{% csrf_token %}標籤。

防禦原理:

  1. 渲染模板文件時在頁面生成一個名字叫做csrfmiddlewaretoken的隱藏域。
  2. 服務器交給瀏覽器保存一個名字為csrftoken的cookie信息。
  3. 提交表單時,兩個值都會發給服務器,服務器進行比對,如果一樣,則csrf驗證通過,否則失敗。

8. 驗證碼

在用戶註冊、登錄頁面,為了防止暴力請求,可以加入驗證碼功能,如果驗證碼錯誤,則不需要繼續處理,可以減輕業務服務器、數據庫服務器的壓力。

9. 反向解析

當某一個url配置的地址發生變化時,頁面上使用反向解析生成地址的位置不需要發生變化。

根據url 正則表達式的配置動態的生成url。

在項目urls中包含具體應用的urls文件時指定namespace;

urlpatterns-[
    url(r'^admin/',include(admin.site.urls)),
    # 包含應用的urls文件	
    url(r'^',include('booktest.urls'),namespace='booktest'),
]

在應用的urls中配置是指定name;

urlpatterns-[
    url(r'^index1/$',views.index1,name='index1'),
    url(r'^index2/$',views.index2,name='index2'),
]
在模板文件中使用時,格式如下:
{% url 'namespace名字:name' %} 
例如{% url 'booktest:fan2'%}
帶位置參數:
{% url 'namespace名字:name' 參數 %} 
例如{% url 'booktest:fan2' 1%}
帶關鍵字參數:
{% url 'namespace名字:name' 關鍵字參數 %} 
例如{% url 'booktest:fan2' id=1 %}
在重定向的時候使用反向解析:
from django.core.urlresolvers import reverse
無參數:
reverse('namespace名字:name名字')
如果有位置參數
reverse('namespace名字:name名字', args = 位置參數元組)
如果有關鍵字參數
reverse('namespace名字:name名字', kwargs=字典)

Django 其他技術

其他技術

1. 靜態文件

1.1 使用

在 網頁使用的css文件,js文件和圖片叫做靜態文件。

  1. 新建靜態文件夾 static。
  2. 配置靜態文件所在的物理目錄。Settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
STATIC_ROOT = "/home/zic/桌面/singleBlog/singleBlog/static"

STATIC_URL設置訪問靜態文件對應的url。

STATICFILES_DIRS設置靜態文件所在的物理目錄。

動態生成靜態文件的路徑。

1.2 加載目錄

STATICFILES_FINDERS=('django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder')

2. 中間件

image.png

中間件函數是django框架給我們預留的函數接口,讓我們可以干預請求和應答的過程。

2.1 獲取瀏覽器端的ip地址

使用request對象的META屬性:request.META[『REMOTE_ADDR』]

2.2 使用中間件

image.png

  1. 新建middleware.py文件。
  2. 定義中間件類。

image.png

在類中定義中間件預留函數。
💡 init:服務器響應第一個請求的時候調用。
💡 process_request:是在產生request對象,進行url匹配之前調用。
💡 process_view:是url匹配之後,調用視圖函數之前。
💡 process_response:視圖函數調用之後,內容返回給瀏覽器之前。
💡 process_exception:視圖函數出現異常,會調用這個函數。
如果註冊的多個中間件類中包含process_exception函數的時候,調用的順序跟註冊的順序是相反的。

  1. 註冊中間件類。
    image.png

3. Admin後台管理

3.1 使用

  1. 本地化。語言和時區本地化。
  2. 創建超級管理員。
    python mange.py createsuperuser
  3. 註冊模型類。
  4. 自定義管理頁面。
    自定義模型管理類。
    註冊模型類的時候給register函數添加第二個參數,就是自定義模型管理類的名字。

3.2 模型管理類相關屬性

  1. 列表頁相關的選項。
  2. 編輯頁相關的選項。

4. 上傳圖片

商品銷售網站。

4.1 配置上傳文件保存目錄

  1. 新建上傳文件保存目錄。

image.png

  1. 配置上傳文件保存目錄。
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

4.2 後台管理頁面上傳圖片

  1. 設計模型類。
class PicTest(models.Model):
    """上傳圖片"""
    good_pic = models.ImageField(upload_to="booktest")
  1. 遷移生成表格。

image.png

  1. 註冊模型類。

4.3 用戶自定義頁面上傳圖片

  1. 定義用戶上傳圖片的頁面並顯示,是一個自定義的表單。

  1. 定義接收上傳文件的視圖函數。
    request對象有一個FILES的屬性,類似於字典,通過request.FILES可以獲取上傳文件的處理對象。
    在django中,上傳文件不大於2.5M,文件放在內存中。上傳文件大於2.5M,文件內容寫到一個臨時文件中。
    Django處理上傳文件的兩個類:
FILE_UPLOAD_HANDLERS= (
"django.core.files.uploadhandler.MemoryFileUploadHandler",
"django.core.files.uploadhandler.TemporaryFileUploadHandler"
)

上傳圖片參考資料:

  1. //python.usyiyi.cn/documents/django_182/topics/http/file-uploads.html
  2. //python.usyiyi.cn/documents/django_182/ref/files/uploads.html#django.core.files.uploadedfile.UploadedFile

5. 分頁

查詢出所有省級地區的信息,顯示在頁面上。

areaInfo.objects.filter(aParent__isnull = True)
  1. 查詢出所有省級地區的信息。
  2. 按每頁顯示10條信息進行分頁,默認顯示第一頁的信息,下面並顯示出頁碼。
  3. 點擊i頁鏈接的時候,就顯示第i頁的省級地區信息。
from django.core.paginator import Paginator
paginator = Paginator(areas, 10) #按每頁10條數據進行分頁

Paginator類對象的屬性:

image.png

Paginator類對象的方法:

image.png

Page類對象的屬性:

image.png

Page類對象的方法:

image.png

分頁參考資料:

//python.usyiyi.cn/translate/django_182/topics/pagination.html

6. 省市縣選擇案例

  1. 顯示省地區信息。
$.get('/prov', function(data){

})
  1. 省改變時在對應的下拉列表框中顯示下級市的信息。
$.get('/city?pid='+pid, function(data){
})

request.GET.get('pid')
或者:
$.get('/city'+$(this).val(), function(data){

})
  1. 市改變時在對應的下拉列表框中顯示下級縣的信息。
$.get('/dis?pid='+pid, function(data){

})
或者:
$.get('/dis'+$(this).val(), function(data){

})

Django settings 配置

"""
Django settings for singleBlog project.

Generated by 'django-admin startproject' using Django 3.2.8.

For more information on this file, see
//docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
//docs.djangoproject.com/en/3.2/ref/settings/
"""

from pathlib import Path
import simpleui, ckeditor
import sys, os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))

# Quick-start development settings - unsuitable for production
# See //docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-3n0*8@=0qc465q+3j_$v73@l$358(85v09%295&&4jm9lr@(e5'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']

# Application definition

INSTALLED_APPS = [
    'ckeditor',
    'simpleui',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',  # 主應用
    'user',  # 用戶中心
    'other',  # 其他
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'singleBlog.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [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',
                'django.template.context_processors.media',  # 用戶上傳
            ],
        },
    },
]

WSGI_APPLICATION = 'singleBlog.wsgi.application'

# Database
# //docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'singleblog',
        'HOST': '127.0.0.1',
        'PORT': 3306,
        'USER': 'root',
        'PASSWORD': 'admin*123'
    }
}

# Password validation
# //docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# //docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = False

# Static files (CSS, JavaScript, Images)
# //docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
STATIC_ROOT = "/home/zic/桌面/singleBlog/singleBlog/static"

# Default primary key field type
# //docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

AUTHENTICATION_BACKENDS = {
    'apps.user.views.MyBackend',
}
# 發送郵件配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# smpt服務地址
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 25
# 發送郵件的郵箱  # ZDJTKDEFODMIXSQD
EMAIL_HOST_USER = '[email protected]'
# 在郵箱中設置的客戶端授權密碼
EMAIL_HOST_PASSWORD = 'XDXXQCOFVKZSIQQQ'
# 收件人看到的發件人
EMAIL_FROM = 'zic博客<[email protected]>'

CKEDITOR_CONFIGS = {
    # django-ckeditor默認使用default配置
    'default': {
        # 編輯器寬度自適應
        'width': 'auto',
        'height': '250px',
        # tab鍵轉換空格數
        'tabSpaces': 4,
        # 工具欄風格
        'toolbar': 'Custom',
        # 工具欄按鈕
        'toolbar_Custom': [
            # 表情 代碼塊
            ['Smiley', 'CodeSnippet'],
            # 字體風格
            ['Bold', 'Italic', 'Underline', 'RemoveFormat', 'Blockquote'],
            # 字體顏色
            ['TextColor', 'BGColor'],
            # 鏈接
            ['Link', 'Unlink'],
            # 列表
            ['NumberedList', 'BulletedList'],
            # 最大化
            ['Maximize']
        ],
        # 加入代碼塊插件
        'extraPlugins': ','.join(['codesnippet', 'widget', 'lineutils']),

    }
}
Tags: