Django 基礎

一 概述

1 基本概述

Python下有許多款不同的 Web 框架。Django是重量級選手中最有代表性的一位。許多成功的網站和APP都基於Django。

Django是一個開放源代碼的Web應用框架,由Python寫成。

Django遵守BSD版權,初次發佈於2005年7月, 並於2008年9月發佈了第一個正式版本1.0 。

Django採用了MVC的軟件設計模式,即模型M,視圖V和控制器C。

所以Django的設計目標就是一款大而全,便於企業開發項目的框架,因此企業應用較爲廣泛

2 優點

1 能夠快速開發,如Auth,Cache模板
2 MVC設計模式
3 實用的管理後臺
4 自帶ORM,Template,Form,Auth核心
5 組件
6 簡潔的URL設計
7 周邊插件豐富

3 缺點

重量級,因爲東西大而全
同步阻塞

4 Django版本

Django version python version
1.8 2.7 3.2 3.3 3.4 3.5
1.9 1.10 2.7 3.4 3.5
1.11 2.7 3.4 3.5 3.6
2.0 3.4 3.5 3.6
2.1 3.5 3.6 3.7

建議不要隨便嘗試新版本,因爲其可能會有問題

二 Django 基本安裝

1 安裝

1 安裝虛擬環境

python3.5.4 Django 版本2.0

mkdir test  // 創建test目錄
pyenv   virtualenv  3.5.4  test  //創建test虛擬賬號
cd test/
pyenv local test  //設置虛擬環境 

結果如下

Django 基礎

2 安裝

 pip  install  django==2.0

Django 基礎

3 創建Django項目

創建名稱爲test.dj的項目

django-admin  startproject  testdj  .

項目結構如下

Django 基礎

上述命令就在當前目錄中創建了Django項目的初始化文件,點表示項目的根目錄

重要文件說明

manage.py:本項目管理的命令行工具,應用創建,數據庫遷移,等都需要其完成,
testdj/settings.py: 本項目配置文件,數據庫參數等 
testdj/urls.py:URL路徑映射配置,默認情況下,只配置了/admin的路由
testdj/wsgi:定義WSGI接口信息,一般無需改動

4 pycharm 連接遠端Linux服務環境

設置本地項目路徑

Django 基礎

連接遠端項目

Django 基礎

連接遠端

Django 基礎

遠端地址

Django 基礎

SSH連接

Django 基礎

若端口不同可修改端口

配置密碼

Django 基礎

配置項目映射和相關項目環境

Django 基礎

結果如下

Django 基礎

數據拉取

Django 基礎

5 數據庫相關配置

數據庫必須啓動,其用戶名密碼必須存在

Django 基礎

創建test庫

Django 基礎

Django連接配置

Django 基礎

相關參數詳解

'ENGINE' : 連接引擎
'NAME':連接數據庫用戶名
'PASSWORD':連接數據庫密碼
'HOST':數據庫主機IP地址,缺省字符串,代表localhost,如果是'/'開頭表示Unix socket 連接
'POST':端口


數據庫引擎ENGINE

內建的引擎有

django.db.backends.postgresql
django.db.backends.mysql
django.db.backends.sqlite3
django.db.backends.oracle

django 在配置時需要加載mysql的配置,因此其是全局配置,連接數據庫的配置,在啓動時必須被加載,其中settings.py是最早被加載的

數據庫驅動配置

驅動地址

https://docs.djangoproject.com/en/2.2/ref/databases/#mysql-notes

Django支持MySQL 5.5+
Django的官方推薦版本是mysql 1.3.7 +


安裝驅動

 pip install mysqlclient

結果如下

Django 基礎

執行遷移文件,其本身的數據庫配置

python  manage.py   migrate

結果如下

Django 基礎

2 創建應用

1 Linux端命令行創建相關應用

python  manage.py   startapp  testapp

Django 基礎

2 相關目錄結構如下

Django 基礎

3 相關文件詳解

admin.py 管理站點模型的聲明文件

models.py 模型層Model類定義

views.py 定義URL 響應函數

migrations包。數據庫遷移文件生成目錄

apps.py 應用的信息定義文件

4 註冊應用

在 settings.py中,增加testapp應用,目的是爲了後臺管理admin使用。或者遷移 migrate 使用

Django 基礎

3 配置管理後臺

1 創建管理員
設置用戶名爲admin,密碼爲admin123

 ./manage.py  createsuperuser

結果如下

Django 基礎

6 本地化,配置時區和語言設置,在testdj/settings.pt中配置

Django 基礎

7 啓動web Server

修改配置文件允許所有主機訪問

Django 基礎

啓動

 python  manage.py   runserver  0.0.0.0:8000

默認啓動爲8000端口
如下

Django 基礎

Django 基礎

Django 基礎

Django 基礎

三 Django 模板技術

1 概述

如果使用react實現前端的頁面功能,其實Django就沒必要使用模板,它其實就是一個後臺服務器程序,接受請求,響應數據,接口設計就可以是一個純粹的Reasrful 風格

模板的目的就是爲了可視化,將數據按照一定的佈局格式輸出,而不是爲了數據處理,所以一般不會有複雜的邏輯,模板的引入實現了業務邏輯和顯示格式的分離,這樣,在開發中,就可以分工工作,頁面開發完成的頁面佈局設計,後臺開發完成數據處理邏輯的實現

python的模板引擎默認使用Django template language (DTL)構建

2 模板配置

1 設置模板路徑

在settins.py中,設置模板項目的路徑

Django 基礎

名詞解釋

DIRS 列表,定義模板文件的搜索路徑順序

BACKEND 指定項目默認引擎

APP_DIRS 是否運行在每個已安裝的應用中查找模板

BASE_DIR 是項目的根目錄,os.path.join(BASE_DIR,'templates')就是在manage.py這層建立一個目錄templates,這路徑是後面找模板的地方。

2 創建模板文件

項目目錄中添加相關文件夾並在其中創建index.html文件

Django 基礎

3 模板渲染

模板處理2個步驟

1 加載模板
模板是一個文件,需要從磁盤中讀取並加載,要將模板放置在上述指定的目錄中

2 渲染

模板需要使用內容數據來渲染,生成對應的HTML文件內容

4 基本代碼實現

在testdj/urls.py中配置如下

Django 基礎

相關代碼

from django.contrib import admin
from django.urls import path
from  django.conf.urls  import  url   # 導入url用於匹配多個後綴服務
from   django.shortcuts import   render  # 導入渲染模板
def  index(request):
    print  (request)
    print  (type(request))
    return    render(request,'index.html',{'user':'hello world'})

urlpatterns = [
    url(r'^admin/', admin.site.urls),  # 正則匹配,以admin 開頭的調度到admin.site.urls中
    url(r'^index/',index),  #同上
    url(r'^$',index),
]

render 源碼如下

def render(request, template_name, context=None, content_type=None, status=None, using=None):
    """
    Return a HttpResponse whose content is filled with the result of calling
    django.template.loader.render_to_string() with the passed arguments.
    """
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)

上述中還可以傳遞狀態碼等參數,但第一個必須是request,第二個必須是模板名稱,

處理模塊填充相關問題

def render_to_string(template_name, context=None, request=None, using=None):
    """
    Load a template and render it with a context. Return a string.

    template_name may be a string or a list of strings.
    """
    if isinstance(template_name, (list, tuple)):
        template = select_template(template_name, using=using)  # 解決模板找到模板名稱的問題,在配置文件中尋找
    else:
        template = get_template(template_name, using=using)
    return template.render(context, request)  # 此處是使用模板來填充數據,並將其輸出出來,其中包含請求和響應內容 

搜索模板相關代碼

def get_template(template_name, using=None):
    """
    Load and return a template for the given name.

    Raise TemplateDoesNotExist if no such template exists.
    """
    chain = []
    engines = _engine_list(using)
    for engine in engines:
        try:
            return engine.get_template(template_name)
        except TemplateDoesNotExist as e:
            chain.append(e)

    raise TemplateDoesNotExist(template_name, chain=chain)

index 代碼如下

Django 基礎

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主頁</title>
</head>
<body>
test <h1>{{ user  }}</h1>  <!--此處必須和前面的最後一列中的名稱相對應,否則將不能被識別到-->
</body>
</html>

Django 基礎

Django 基礎

加載方法相當於使用open將文件打開,渲染方法將其中的{{}}中的內容進行填充,填充好後交給httpresponse 的body,進行傳遞頭部,約定編碼,相關壓縮情況,當正文來了後先看編碼格式,後看title,最後加載body的渲染內容


下載是不渲染的,發起HTTP請求,服務器將文件打開,文件流傳輸,其類型是普通文件,其不會渲染成dom樹,其不會做相關的操作,下載不需要dom,只有轉換成DOM才能渲染,

from django.contrib import admin
from django.urls import path
from  django.http  import HttpResponse,JsonResponse
from  django.conf.urls  import  url   # 導入url用於匹配多個後綴服務
from   django.shortcuts import   render  # 導入渲染模板
def  index(request):
    print  (request)
    print  (type(request))
    return    JsonResponse({'user':'hello world'})  # 此處返回結果爲一個json格式的數據

urlpatterns = [
    url(r'^admin/', admin.site.urls),  # 正則匹配,以admin 開頭的調度到admin.site.urls中
    url(r'^index/',index),  #同上
    url(r'^$',index),
]

構建結果如下

Django 基礎

3 模板操作(DTL)

https://docs.djangoproject.com/en/2.2/ref/templates/builtins/

1 變量

語法 {{variable}}

變量名由字母,數字,下劃線,點號組成


點號使用時,需要遵循的順序:
1 字典查找,如foo['bar'],把foo當做字典,bar當做key
2 屬性或方法的查找,如foo.bar 是把foo當做對象,bar當做屬性或者方法
3 數字索引查找,如foo[bar],把foo當做列表一樣,將使用索引訪問


如果變量未能找到,則缺省插入空字符串

在模板中調用方法,不能加小括號,自然也不能傳遞參數

{{ my_dict.keys }} 這樣是對的,不能寫成 {{ my_dict.keys() }}

2 模板標籤

1 if/else 標籤

基本語法如下
{% if condition %}
... display
{%end%}

或者
{% if condition1 %}
..display 1
{% elif condition2 %}
...display 2
{% else %}
...display 3
{% endif %}

條件也支持and,or,not
注意:因爲這些標籤是斷開的,所以不能像python一樣使用鎖緊就可以表示出來,必須有一個結束表親,如 endif endfor

2 for 標籤

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主頁</title>
</head>
<body>
<ul>
    {% for  x  in  name %}
    <li>  {{ x }}   </li>
    {% endfor %}
</ul>

</body>
</html>

下面是便利字典的值

    return  render(request,'index.html',{'name':dict(zip('abcd',range(4)))})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主頁</title>
</head>
<body>
<ul>
    {% for  x  in  name.values %}  
    <li>  {{ x }}   </li>
    {% endfor %}
</ul>

</body>
</html>

結果如下

Django 基礎

變量 說明
forloop.counter 當前循環從1開始計數
forloop.counter 0 當前循環從0開始計數
forloop.revcounter 從循環的末尾開始倒計數到1
forloop.revcounter0 從循環的末尾開始倒計數到0
forloop.first 第一次進入循環
forloop.last 最後一次進入循環
forloop.parentloop 循環嵌套時,內存當前玄幻的外層循環
    return  render(request,'index.html',{'name': [1,2,3,4,5,6]})

翻轉,此處僅限於列表

<ul>
    {% for  x  in  name  reversed  %}
    <li>  {{ x }}  </li>
        {% empty %}
        <li>  default  </li>
    {%endfor%}
</ul>

empty ,爲空或者不存在時執行此命令

如下

<ul>
    {% for  x  in  mysql  reversed  %}
    <li>  {{ x }}  </li>
    {% empty %}
    <li>  default </li> 
    {%endfor%}
</ul>

此處的mysql是不存在的,因此下面的結果是

Django 基礎


後端代碼如下

    return  render(request,'index.html',{'name': dict(zip('abcd',range(4)))})
<ul>
    {% for  k,v  in  name.items %}
    <li>   {{ forloop.first }} </li>
    <li>   {{ forloop.last  }} </li>
    {%endfor%}
</ul>

<h1> 分割線 </h1>

<ul>
    {% for  k,v  in  name.items %}
    <li>   {{ forloop.counter}} {{ k }}   {{ v }} </li>
    {%endfor%}
</ul>

<h1>  分界線 </h1>

<ul>
    {% for  k,v  in  name.items %}
    <li>   {{ forloop.counter0 }} {{ k }}   {{ v }} </li>
    {%endfor%}
</ul>

結果如下

Django 基礎

3 ifequal/ifnotequal 標籤

{% ifequal %} 標籤比較兩個值,當其相等時,顯示在其標籤之間的所有值,

{%ifequal user currentuser %}
<h1> welcome! </h1>
{% endifequal %}

和{% if %}類似,{% ifequal %} 支持可選的 {% else %}標籤。


後端代碼如下

    return  render(request,'index.html',{'name': 'mysql'})

顯示層代碼如下

{% ifequal  name  'mysql' %}
    <h1> Site </h1>
{%else%}
<h1>Not Site </h1>
{%endifequal%}
</body>
</html>

Django 基礎

4 其他標籤

csrf_token 用於跨站請求僞造保護,防止跨站***的

{% csrf_token%}

3 註釋標籤

單行註釋

{#這是一個註釋#}

多行註釋

{% comment %}
這是多行註釋
{%endcomment%}

4 過濾器

模板過濾器可以在變量被顯示之前修改它

語法 {{ 變量 | 過濾器 }}

過濾器使用管道符 | , 例如 {{name| lower}} , {{name}} 變量被過濾器 lower 處理後,文檔大寫轉換文本爲小寫。

過濾管道可以被套接,一個過濾器管道的輸出又可以作爲下一個管道的輸入,例如{{my_list | first | upper }},將列表第一個元素並將其轉換爲大寫。

過濾器傳遞參數
有些過濾器可以被傳遞參數,過濾器的參數跟隨冒號之後並且總是以雙引號包含

如 {{bio| trunactewords:"30"}},截取顯示變量的bio的前30個詞。
{{my_list | join:"."}}將my_list的所有元素使用逗號連接起來

過濾器 說明 舉例
first 取列表第一個元素
last 去列表最後一個元素
yesno 變量可以是 True,False,None,yesno的參數給定的逗號分隔的三個值,返回3個值中的一個。True對應飛一個,False對應第二個,None對應第三個,如果參數只有2個,則None等效於False處理 {{value yesno:"yeah,no,maybe"}}
add 加法,參數是負數就是減法 數字加{{value add:"100"}} 列表合併{{mylist add:newlist}}
divisibleby 能否被整除 {{vaule divisibleby:"3"}}能夠被3整除返回True
addslashes 在反斜槓,單引號或者雙引號前面加上反斜槓 {{value addslashes}}
length 返回變量的長度 {% if my_list length >1 %}
default 變量等價False則使用缺省值 {{value default:"nothing"}}
default_if_none 變量爲None使用缺省值 {{value default_if_none:"noting"}}

練習

計數返回一種類型的值,偶數返回一種類型的顏色

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主頁</title>
</head>
<body>
<u1>
{% for  v  in  name.values %}
    {% if   forloop.counter0|divisibleby:"2" %}
    <li style="color:red"> {{  v  }} </li>
    {% else %}
    <li style="color:seagreen">  {{ v }} </li>
    {% endif %}
{% endfor %}
</u1>
</body>
</html>

第二種

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主頁</title>
</head>
<body>
<u1>
{% for  v  in  name.values %}
    <li style='color: {{ forloop.counter0 | divisibleby:"2"| yesno:"red,blue"}}'>{{v}}</li>
{% endfor %}
</u1>
</body>
</html>

結果如下

Django 基礎

四 模型操作

1 管理器對象

Django 會爲模型提供一個object對象,其是Django.db.models.manager.Manager類型,用於與數據庫交互,當定義模型類的時候沒有指定管理器,則Django會爲模型類提供一個object管理器。

如果在模型中手動指定管理器後,Django不在提供默認的object管理器了

管理器是Django的模型進行數據庫查詢操作的接口,Django應用的每一個模型都至少擁有一個管理器。

Django 基礎

2 查詢

1 查詢集

查詢會返回結果的集,是Django.db.models.query.QuerySet類型
其是惰性求值,和sqlalchemy一樣,結果就是查詢的集。
其是可迭代對象。


1 惰性求值:
創建查詢集不會帶來任何數據庫的訪問,直到調用數據時,纔會訪問數據庫,在迭代,序列化,if語句中都會立即求值。

2 緩存
每一個查詢都包含一個緩存,來最小化對數據庫的訪問
新建查詢集,緩存爲空,首次對查詢集請求值時,會發生數據查庫查詢,Django會把查詢的結果緩存在這個緩存中,並返回請求的結果,接下來對查詢集的求值將使用緩存的結果。


觀察下面2個例子是要看真正生成的語句了

1 沒有使用緩存,每次都要查詢數據庫,查詢了兩次
[user.name for user in User.objects.all()]
[user.name for user in User.objects.all()]

2 下面的語句使用緩存,因爲其使用同一個結果集
qs = User.objects.all()

[user.name for user in qs ]
[user.name for user in qs ]

2 限制查詢集(切片)

查詢集對象可以直接使用索引下表的方式(不支持負向索引),相當於SQL語句中的limit 和 offset 字句,注意使用索引返回的新結果集,依然是惰性求值,不會立即查詢。


qs = User.objects.all()[20:40]

SQL 等價:Limit 20 offset 20

qs = User.obeject.all()[20:30]

SQL 等價:Limit 10 offset 20

3 過濾器

column column
all() Text
filter() 過濾,返回滿足條件查詢的數據
exclude() 排除,排除滿足條件的數據
order_by()
values() 返回一個對象的字典的列表,像JSON

下屬等價
filter(k1=v1).filter(k2=v2)等價於 filter(k1=v1,k2=v2)
filter(pk=10)這裏pk指的是主鍵,不用關心主鍵的名字字段,當然也可以使用主鍵來進行相關的過濾操作


返回單值的情況

column column
get() 僅返回單個滿足條件的對象,如果未能返回對象則排除DoesNotExists異常,如果能返回多條,拋出MultipleObjectReturned 異常
count() 返回當前查詢的總條數
first() 返回第一個對象
last() 返回最後一個對象
exist() 判斷查詢集中是否有數據,如果有則返回True

字段查詢(field Lookup) 表達式
字段查詢表達式可以作爲filter(),exclude(),get() 的參數,實現的是where字句的功能

語法: 屬性(字段) 名稱_比較運算符=值
注意: 屬性名和運算符之間使用雙下劃線

column column
exact filter(isdeleted=False) filter(isdeleted__exact=False) 嚴格等於,可以省略不寫
contains exclude(title__contains='天') 是否包含,大小寫敏感,等價於 like '%天%'
startswith endswith filter(title__startswith='天') 以什麼開頭,以什麼結尾,大小寫敏感
isnull isnotull filter(title__isnull=False) 是否爲null
iexact,iconains,istartswitch,iendswith i 的意思是忽略大小寫
in filter(pk__in=[1,2,3,4]) 是否在指定返回的數據中
gt,gte,lt,lte filter(id__gt=3) filter(pk__ltd=3),filter(pub_date__gt=date(2000,1,1)) 大於,小於等
year,month,day,week_day,hour,minute,second filter(pub_date__year=2000) 對日期類型屬性處理

4 Q對象

雖然Django 提供傳入條件的方式,但是不方便,它還提供了Q對象來解決。

Q對象是Django.db.modules.Q,可以使用 &(and) , |(or)操作符來組成邏輯表達式,~ 表示not

from django.db.models  import Q 
User.objects.filter(Q(pk__lt=6))  # 不如直接寫 User.objects.filter(pk<6)

User.objects.filter(pk__gt=6).filter(pk_lt=10)  #與 
User.objects.filter(Q(pk__gt=6) &  (pk__lt=10))  # 與 

User.objects.filter(Q(pk=6) | Q(pk=10))  # 或 
User.objects.filter(~Q(pk__lt<6))  # 非

可使用&| 和Q對象來構造複雜的邏輯表達式
過濾器函數可以使用一個或多個Q對象
如果混用關鍵字參數和Q對象,那麼Q對象必須位於關鍵字參數的前面,所有參數都將and在一起

3 創建表字段操作

1 模型選項

字段類 說明
AutoField 自增的整數字段,如果不指定Django會爲模型類型自動增加主鍵字段
BooleanField 布爾值字段,True和False,對應表單控件CheckboxInput
NullBooleanField 比BooleanField 多一個空值
CharField 字符串,max_length 設定字符串長度,表單控件TextInput
TextField 大文本字段,一般超過4000個字符使用,對應表單控件Textarea
IntegerField 整數字段
BigIntegerField 更大整數字段,8字節
DecimalField 使用Python的Decimal實例表示十進制的浮點數,max_digits 總位數,decimal_places 小數點後的位數
FloatField python中的Float實例表示的浮點數
DateField 使用python的datetime.date 實例表示的日期,auto_now=False每次修改對象自動設置爲當前時間,auto_now_add=False對象第一次創建時自動設置爲當前時間,auto_now_add,auto_now,default互斥,對應控件爲TextInput,關聯了一個js編寫的日曆控件
TimeField 使用python的datetime.time實例表示時間,參數同上
DateTimeField 使用python的datetime.datetime實例表示的時間,參數同上
FileField 一個上傳文件的字段
ImageField 繼承了FileField 的所有屬性和方法,但是對上傳文件進行校驗,確保是一個有效的圖片

2 字段選項

說明
db_column 表中字段的名稱,如果未指定,則使用屬性名
primary_key 是否爲主鍵
unique 是否是唯一
default 缺省值,這個缺省值不是數據庫字段的缺省值,而是新對象產生的是夠被填入的缺省值
null 表的字段是否可以爲null,默認爲False
db_index 字段是否有索引

3 關係類型字段類

說明
ForeignKey 外鍵,表示一對多 ForeignKey('production.Manufacturer')自關聯 ForeiginKey('self')
ManyToMaryField 表示多對多
OneToOneField 表示一對一

一對多時,自動創建會增加_id後綴。

從一訪問多,使用 對象.小寫模型類_set
從一訪問一,使用 對象.小寫模型類
訪問 id 對象.屬性_id

4 創建User的Model 類

基類 models.Model
表名不指定默認使用<appname>_<model_name>,使用Meta類修改表名

Django 基礎

相關代碼如下

from django.db import models
# Create your models here.
class User(models.Model):
    class Meta:
        db_table='user'  # 定義數據庫表名
    id = models.AutoField(primary_key=True)  # 定義主鍵自增字段
    name=models.CharField(max_length=48,null=False)  # 定義name爲浮點型,且其不能爲空
    email=models.CharField(max_length=64,unique=True,null=False)  # 定義郵件爲浮點類型,且其必須唯一,不能爲空
    password=models.CharField(max_length=128,null=False) # 定義密碼類型,其爲浮點數,且不能爲空
    def __repr__(self):
        return   '<user  {}  {}>'.format(self.id,self.name)
    __str__=__repr__

遷移 migration

遷移:從模型定義生成數據庫的表
1 在項目根目錄執行下面文件生成遷移文件

 python manage.py makemigrations

結果如下

Django 基礎

修改過Model類,還需要調用makemigrations,然後migrate,遷移文件的序號會增加

注意:遷移的應用必須在settings.py 的 INSTALLED_APPS 中註冊


2 在項目的根目錄執行遷移生成數據庫的表

python  manage.py migrate

結果如下

Django 基礎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章