今天開始對Django開始學習了,對於一個小白來說經常聽到開發說什么MVC、MTV的,感覺好高深的樣子,下面在學習Django之前先來介紹一下什么是MVC&MTV。
一、MVC&MTV
MVC:全名Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件設計典范,用一種業務邏輯、數據、界面顯示分離的方法組織代碼,將業務邏輯聚集到一個部件里面,在改進和個性化定制界面及用戶交互的同時,不需要重新編寫業務邏輯。
-
M(Models) --> 操作數據庫
-
V(Views) --> 放置HTML模板
-
C(Controller) --> 處理用戶請求
MTV:有些WEB框架覺得MVC的字面意思很別扭,就給它改了一下。view不再是HTML相關,而是主業務邏輯了,相當於控制器。html被放在Templates中,稱作模板,於是MVC就變成了MTV。這其實就是一個文字游戲,和MVC本質上是一樣的,換了個名字和叫法而已,換湯不換葯。
-
M(Models) --> 操作數據庫
-
T(Template) --> 放置HTML模板
-
V(Views) --> 處理用戶請求
二、Django的工作方式
用戶在瀏覽器中輸入URL后回車,瀏覽器會對URL進行檢查,首先判斷協議,如果是HTTP就按照Web來處理,然后調用DNS查詢,將域名轉換為IP地址,然后通過網絡傳輸到達對應Web服務器,服務器對URL進行解析后,調用View中的邏輯,其中涉及到Model與數據庫的進行交互,然后將數據發送到Template進行渲染,發送到瀏覽器中,瀏覽器以合適的方式呈現給用戶。
三、項目和APP
1、Django安裝
1
2
3
4
5
6
|
pip install django
#安裝最新版本的Django
pip install
-
v django
=
=
1.7
.
1
#或者指定安裝版本
#如果在Windows中裝了多個版本的python,可以通過python3 -m pip install Django進行安裝
|
2、創建Django項目
通過pythonIDE:Pycharm創建 File-->New Project -->Django
Linux命令行中創建:
1
|
django
-admin
.py startproject mysite
|
Django將自動生成下面的目錄結構:
1
2
3
4
5
6
7
8
9
|
[root@brand007 soft]
# tree mysite/
mysite/
├── manage.py
#Django管理主程序
├── mysite
│ ├── __init__.py
│ ├── settings.py
#主配置文件
│ ├── urls.py
#URL路由系統文件
│ └── wsgi.py
#網絡通信接口
└── template
#該目錄放置HTML文件模板
|
3、創建APP
在每個Django項目中可以包含多個APP,相當於一個大型項目中的分系統、子模塊、功能部件等等,相互之間比較獨立,但也有聯系,所有的APP共享項目資源。
執行命令:
1
2
3
|
python manage.py startapp cmdb
#創建一個名字為cmdb的app
|
1
2
3
4
5
6
7
8
9
10
|
[root@brand007 mysite]
# tree cmdb/
cmdb/
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
└── views.py
|
4、編寫路由規則
路由都在urls文件里,它將瀏覽器的URL映射到響應的業務處理邏輯。
1
2
3
4
5
6
7
8
|
from
django.conf.urls
import
url
from
django.contrib
import
admin
from
cmdb
import
views
urlpatterns
=
[
#url(r'^admin/', admin.site.urls),
url(r
'^index/'
, views.index),
]
|
5、編寫業務處理邏輯views
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from
django.shortcuts
import
render
#首先導入HttpResponse模塊
from
django.shortcuts
import
HttpResponse
# Create your views here.
def
index(request):
"""
:param request: 這個參數必須有,類似self的默認規則,可以改,它封裝了用戶請求的所有內容
:return: 不能直接返回字符串,必須有HttpResponse這個類封裝起來,這是Django的規則
"""
return
HttpResponse(
"Hello,World"
)
|
6、運行Web服務
1
2
3
|
命令行:python manage.py runserver
127.0
.
0.1
8080
Pycharm:點擊執行按鈕或通過點擊edit configurations進行執行
|
訪問地址:http://127.0.0.1:8000/index/ 可以看到我們定義的返回結果"Hello,World"。
7、返回HTML文件
上面的例子返回給用戶瀏覽器的是一個字符串,在實際工作中肯定沒這么干的,通常我們都是將渲染后的HTML文件返回給用戶。
7.1 首先定義一個HTML文件index.html:
1
2
3
4
5
6
7
8
9
10
11
|
<!DOCTYPE html>
<
html
lang
=
"en"
>
<
head
>
<
meta
charset
=
"UTF-8"
>
<
title
>first Django</
title
>
</
head
>
<
body
>
<
h1
style
=
"background-color: black;color: green"
>Hello,world!!!</
h1
>
</
body
>
</
html
>
|
7.2 然后,修改我們的views文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
from
django.shortcuts
import
render
#首先導入HttpResponse模塊
from
django.shortcuts
import
HttpResponse
# Create your views here.
def
index(request):
"""
render方法用來渲染(其實就是打包的意思)
:param request: 這個參數必須有,類似self的默認規則,可以改,它封裝了用戶請求的所有內容
:return: 不能直接返回字符串,必須有HttpResponse這個類封裝起來,這是Django的規則
"""
return
render(request,
"index.html"
,)
|
7.3 為了讓Django知道我們的HTML模板在什么地方,需要在settings文件中進行配置,默認是配置好的無需修改。
1
2
3
4
|
TEMPLATES
=
[
{
'BACKEND'
:
'django.template.backends.django.DjangoTemplates'
,
'DIRS'
: [os.path.join(BASE_DIR,
'templates'
)]
|
配置完成后,重啟Web服務,在瀏覽器里可以看到帶樣式的"Hello,World!!!"
8、使用靜態文件
我們已經可以將HTML文件返回給用戶了,在實際工作中我們還會用到CSS,JS的這些插件的功能。在Django中,我們將這些靜態文件放在static目錄中。
8.1 創建static目錄,並將下載好的插件放到該目錄下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[root@brand007 soft]
# tree mysite/
mysite/
├── cmdb
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── manage.py
├── mysite
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-35.pyc
│ │ └── settings.cpython-35.pyc
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── static
│ └── jquery-1.12.4.js
└── template
|
8.2 為了讓我們的Django找到這個目錄,需要對settings做以下修改:
1
2
3
4
5
6
7
8
|
STATIC_URL
=
'/static/'
STATICFILES_DIRS
=
(
os.path.join(BASE_DIR,
'static'
),
)
#注意:1、STATICFILES_DIRS這個變量名必須這樣定義
# 2、os.path.join(BASE_DIR,'static'),因為是一個元組,最后面的逗號不能忽略,必須注意
|
8.2 最后我們的index.html引入js文件:
1
2
3
4
5
6
7
8
9
10
11
|
<!DOCTYPE html>
<html lang=
"en"
>
<head>
<meta charset=
"UTF-8"
>
<title>first Django</title>
</head>
<body>
<h1 style=
"background-color: black;color: green"
>Hello,world!!!</h1>
<script src=
"/static/jquery-1.12.4.js"
></script>
</body>
</html>
|
9、返回動態頁面
通常我們會根據用戶的數據,進行處理后在返回給用戶。這時候,Django采用自己的模板語言,類似jinja2,根據提供的數據,替換掉HTML中的相應部分,請看下例。
修改views.py文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
from
django.shortcuts
import
render
from
django.shortcuts
import
HttpResponse
# Create your views here.
# 處理用戶請求
USER_INPUT
=
[
{
'user'
:
'jack'
,
'pwd'
:
'123'
},
{
'user'
:
'eric'
,
'pwd'
:
'456'
},
]
def
index(request):
# ...
# 判斷用戶是否是POST請求
if
(request.method
=
=
'POST'
):
user
=
request.POST.get(
'user'
,
None
)
pwd
=
request.POST.get(
'pwd'
,
None
)
temp
=
{
'user'
: user,
'pwd'
: pwd}
USER_INPUT.append(temp)
return
render(request,
'index.html'
, {
'data'
: USER_INPUT })
|
修改index.html:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<!DOCTYPE html>
<
html
lang
=
"en"
>
<
head
>
<
meta
charset
=
"UTF-8"
>
<
title
></
title
>
</
head
>
<
body
>
<
h1
>用戶輸入:</
h1
>
<
form
action
=
"/index/"
method
=
"POST"
>
<
input
type
=
"text"
name
=
"user"
/>
<
input
type
=
"text"
name
=
"pwd"
/>
<
input
type
=
"submit"
value
=
"提交"
/>
</
form
>
<
h1
>數據展示:</
h1
>
<
table
border
=
"1"
>
{% for item in data %}
<
tr
>
<
td
>{{ item.user }}</
td
>
<
td
>{{ item.pwd }}</
td
>
</
tr
>
{% endfor %}
</
table
>
<
script
src
=
"/static/jquery-1.12.4.js"
></
script
>
</
body
>
</
html
>
|
重新項目,當我們在input框里輸入信息后,點擊提交后會報下面的錯誤:
這是Django的一個跨站請求保護機制,我們現在還用不到這個功能,因此需要在settings文件里將其注釋掉。
注釋掉后再次刷新,可以看到我們提交的數據:
10、與數據庫交互
上例中我們我們提交的數據都是保存在了內存中,一旦關閉重新打開數據就會丟失,這里就引出了Django和數據庫的交互,還是上面的例子,我們通過數據庫,來講用戶提交的信息,持久化到數據庫中。
首先,在settings文件中將我們的APP添加進去:
不注冊它,數據庫就不知道該給那個app創建表了,然后我們在settings中指定數據庫的相關參數,下面的例子我們使用自帶的sqlite數據庫:
使用MySQL數據庫,配置如下:
修改models.py,來常見數據庫:
1
2
3
4
5
6
7
|
from
django.db
import
models
# Create your models here.
class
UserInfo(models.Model):
#創建的類必須繼承models.Model這個類,這是固定寫法
user
=
models.CharField(max_length
=
32
)
pwd
=
models.CharField(max_length
=
32
)
|
這里我們創建了2個字段,分別為用戶名和密碼長度為32,接下來我們需要執行兩條命令來讓Django自動給我們創建數據庫:
1
2
3
4
5
6
7
8
9
10
|
#首先執行
python manage.py makemigrations
#執行結果:
E:\Python_project\mysite>python3 manage.py makemigrations
Migrations
for
'cmdb'
:
cmdb\migrations\
0001_initial
.py:
-
Create model UserInfo
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#其次執行
python manage.py migrate
#執行結果:
E:\Python_project\mysite>python3 manage.py migrate
Operations to perform:
Apply
all
migrations: admin, auth, cmdb, contenttypes, sessions
Running migrations:
Applying contenttypes.
0001_initial
... OK
Applying auth.
0001_initial
... OK
Applying admin.
0001_initial
... OK
Applying admin.
0002_logentry_remove_auto_add
... OK
Applying contenttypes.
0002_remove_content_type_name
... OK
Applying auth.
0002_alter_permission_name_max_length
... OK
Applying auth.
0003_alter_user_email_max_length
... OK
Applying auth.
0004_alter_user_username_opts
... OK
Applying auth.
0005_alter_user_last_login_null
... OK
Applying auth.
0006_require_contenttypes_0002
... OK
Applying auth.
0007_alter_validators_add_error_messages
... OK
Applying auth.
0008_alter_user_username_max_length
... OK
Applying cmdb.
0001_initial
... OK
Applying sessions.
0001_initial
... OK
|
最后在修改我們的業務邏輯views.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
from
django.shortcuts
import
render
from
django.shortcuts
import
HttpResponse
from
django.shortcuts
import
redirect
from
cmdb
import
models
# Create your views here.
# 處理用戶請求
def
index(request):
# ...
# 判斷用戶是否是POST請求
# return redirect('http://baidu.com')
# return redirect('')
if
(request.method
=
=
'POST'
):
user
=
request.POST.get(
'user'
,
None
)
pwd
=
request.POST.get(
'pwd'
,
None
)
models.UserInfo.objects.create(user
=
user,pwd
=
pwd)
data_list
=
models.UserInfo.objects.
all
()
# [UserInfo對象,UserInfo對象,。。。]
# for item in data_list:
# print(item.user,item.email)
return
render(request,
'index.html'
, {
'data'
: data_list })
|
重啟程序,這樣我們就可以將用戶提交的數據持久化到數據庫了 。