說明:我是先上手做一些簡單的例子,然后在嘗試的過程中理解Django的原理,筆記也是按這個思路來的。
一、Django結構與基本文件介紹
1. django-admin.py
工程管理工具,主要用於創建項目和app等。
例:django-admin.py startproject project_example
會在當前目錄下創建一個名為project_example的工程,目錄結構如下:
|-- project_example
| |--project_example
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- wsgi.py
| |-- manage.py
2. manage.py
命令行工具,用於和Django項目進行交互。
比如:
python manage.py startapp app_example //創建名為app_example的app
python manage.py runserver 0.0.0.0:8000 //啟動app服務,0.0.0.0是讓其他電腦可以連接到服務器,8000是端口,默認就是8000
python manage.py syncdb //連接數據庫創建表,較早版本,較新的版本已經移除,變成了下面的命令
python manage.py makemigrations
python manage.py migrate
3. settings.py
Django工程的配置文件,主要有以下幾個:
(1)
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app_example', ]
在這里添加我們自己創建的app的目錄名,不添加在這里就無法調用app中的內容。
(2)
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER': 'test', 'PASSWORD': 'test123', 'HOST':'localhost', 'PORT':'3306', }
設置連接數據庫的信息
(3)
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], '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', ], }, }, ]
模板信息,'DIRS'是模板所在路徑,比如在最外層的project_example目錄下建一個模板文件夾templates。則應這樣寫: 'DIRS': [BASE_DIR+"/templates",],
目錄結構如下:
|-- project_example
| |--project_example
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- wsgi.py
| |-- manage.py
| |-- templates
| |-- user_info.html
(4)
LANGUAGE_CODE = 'en-us' //語言 TIME_ZONE = 'UTC' //時間
4. urls.py
該Django項目的URL聲明,一份由Django驅動的網站"目錄"。
一般格式:
from project_example.view import hello urlpatterns = patterns("", ('^hello/$', hello), )
(1) 先導入view對象或者相應的視圖函數。
(2) 然后指定URL與相應函數的對應關系
(3) 當客戶端訪問某個URL時就會調用相應函數
例如:
from project_example import view urlpatterns = patterns("", ('^test1/$', view.test1), ('^test2/$', view.test2), )
當訪問 localhost:8000/test1 時就會調用view.test1()函數,訪問 localhost:8000/test2 時就會調用view.test2()函數.
5. 用不到的文件
__init__.py:空文件,告訴Python該目錄是一個Python包。
wsgi.py: 一個 WSGI 兼容的 Web 服務器的入口,以便運行你的項目
二、一個簡單Django例子的運行流程
1. 創建模板文件,也就是上述的templates/user_info.html
例:
<html>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>用戶信息</title>
<head></head>
<body>
<h3>用戶信息:</h3>
<p>姓名:{{name}}</p>
<p>年齡:{{age}}</p>
</body>
</html>
在模板里,我們只填共用組件,至於那些因‘人’而異的組件就用Django的特殊標簽來代替。
比如這里name和age是因‘人’而異的,所以我們用{{name}}{{age}}這兩個變量表示,具體的值由view.py中的視圖函數去填充。
2. 創建視圖函數
首先在內存的project_example中創建view.py文件,然后在其中添加對象,用於向模板提交數據。
目錄結構如下:
|-- project_example
| |--project_example
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- wsgi.py
| |-- view.py
| |-- manage.py
| |-- templates
| |-- user_info.html
view.py內容:
這里我試了這兩種寫法都可以
from django.shortcuts import render from django.shortcuts import render_to_response def user1(request): name = 'aaa' age = 24
return render_to_response('user_info.html',locals()) def user2(request): name = 'bbb' age = 18 context = {} context['name'] = 'bbb' context['age'] = '18'
return render(request, 'user_info.html', context)
3. 修改urls.py
from django.conf.urls import url from project_example import view urlpatterns = [ url(r'user1/$', view.user1), url(r'user2/$', view.user2), ]
4. 發布服務
python manage.py runserver 0.0.0.0:8000
5.登錄網址
http://localhost:8000/user1/
顯示如下:
用戶信息:
姓名:aaa
年齡:24
http://localhost:8000/user2/
顯示如下:
用戶信息:
姓名:bbb
年齡:18
三、 view.py文件中的視圖函數語法解析(待填充)
1. request 對象
通過例子可以看到,所有的視圖函數都有這個參數 request,那他到底是干嘛的呢?
簡單的來講,request是一個HttpRequest對象,他保存着Django接收到請求的所有信息。
比如請求URL的一些信息:
request.path 除域名以外的請求路徑
request.get_host() 主機名/域名
request.get_full_path() 請求路徑
。。。
其他信息:
request.method 傳輸數據的方式,'GET'或'POST'
request.GET/request.POST 一個字典對象,保存着傳來的數據
更多的信息可以百度一下。
2.reander 和 reander_to_response
reander 和 reander_to_response都是Django提供的返回數據的快捷方式,在視圖函數結束之后,直接調用這兩個方法就可以將數據返回給客戶端,不需要我們自己再調用一堆傳輸函數了。
格式:
from django.shortcuts import render
reander(request,data,...) //request就是我們上面講的那個HttpRequest對象,data就是我們想要傳回去的數據,可以是html文件,也可以是字符串等。
from django.shortcuts import render_to_response
reander_to_response(data,...) //直接寫傳回的數據就行
四、Http通信
這里先只講一下POST通信
1. 創建html模板進行通信
代碼:
<html>
<head>
<meta charset="utf-8" />
<title>Search - w3cschool.cc</title>
</head>
<body>
<form action="/search-post/" method="post"> {% csrf_token %} <input type="text" name="q">
<input type="submit" value="Submit">
</form>
<p>{{ rlt }}</p>
</body>
</html>
2. 內層 project_example 目錄下創建search.py
目錄結構如下:
|-- project_example
| |--project_example
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- wsgi.py
| |-- view.py
| |-- search.py
| |-- manage.py
| |-- templates
| |-- user_info.html
search.py代碼:
from django.shortcuts import render #from django.core.context_processors import csrf 1.2版本之前 #from django.contrib.auth.context_processors import csrf 1.2~1.4版本
from django.template.context_processors import csrf #1.10版本
# 接收POST請求數據
def search_post(request): ctx ={} ctx.update(csrf(request)) if request.POST: ctx['rlt'] = request.POST['q'] else: ctx['rlt'] = 'here'
return render(request, "post.html", ctx)
3.添加urls.py
from django.conf.urls import url from project_example import view from project_example import search urlpatterns = [ url(r'user1/$', view.user1), url(r'user2/$', view.user2), url(r'search-post/$', search.search_post), ]
4.發布+訪問
python manage.py runserver 0.0.0.0:8000
http://localhost:8000/search-post/
5.請求流程
用戶發送請求 -> 服務端執行search_post(),if不成立 -> 顯示post.html頁面 -> 在該頁面點擊提交按鈕之后數據再次傳遞給localhost:8000/search-post/ -> 服務端再次執行search_post(),這次if成立
2.關於APP或JS客戶端POST通信失敗的原因
我在用POST通信時,如果不是通過瀏覽器訪問服務端,就會一直報403的錯誤。
原因是Django的CSRF保護協議,瀏覽器可以自己在頭文件中修改使其符合Django的要求,但JS和APP客戶端修改頭文件是不行的。
具體原因見:
http://blog.csdn.net/ybdesire/article/details/48196843
解決方法見:
http://www.wengweitao.com/corskua-yu-zi-yuan-gong-xiang-cross-origin-resource-sharing.html
首先修改配置,然后在view.py里這樣寫
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def search_post(request):
。。。
五、JSON解析
Python中有專門編碼和解碼JSON的模塊Demjson,他提供了兩個方法
demjson.encode():將 Python 對象編碼成 JSON 字符串
demjson.decode():將已編碼的 JSON 字符串解碼為 Python 對象
例:
import demjson data = [ { 'a' : 1, 'b' : 2, 'c' : 3, 'd' : 4, 'e' : 5 } ] json = demjson.encode(data) print json
結果:[{"a":1,"b":2,"c":3,"d":4,"e":5}] //json字符串
json = '{"a":1,"b":2,"c":3,"d":4,"e":5}'; text = demjson.decode(json) print text
結果:{u'a': 1, u'c': 3, u'b': 2, u'e': 5, u'd': 4} //字典對象
六、數據庫操作
1. 設置setting.py文件中的數據庫配置
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test', 'USER': 'test', 'PASSWORD': 'test123', 'HOST':'localhost', 'PORT':'3306', }
這里面的用戶信息要和電腦上MySQL中的用戶信息相同。
2. Django規定使用模板必須創建APP對象
命令: python manage.py startapp TestModel
目錄結構如下:
|-- project_example
| |--project_example
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- wsgi.py
| |-- view.py
| |-- search.py
| |-- manage.py
| |-- templates
| |-- user_info.html
| |-- TestModel
| |-- __init__.py
| |-- admin.py
| |-- models.py
| |-- tests.py
3. 修改TestModel/models.py文件,Django會根據這個文件創建表
代碼:
from django.db import models class Test(models.Model): name = models.CharField(max_length=20) age = models.IntegerField(max_length=3)
這里指定了一個名為 TestModel_Test 的表。(表名:目錄名_類名)
表中有3個字段:id(默認),name,age
4. 在內層的project_example目錄下創建testdb.py保存執行數據庫操作函數
目錄結構如下:
|-- project_example
| |--project_example
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- wsgi.py
| |-- view.py
| |-- testdb.py
| |-- manage.py
| |-- templates
| |-- user_info.html
| |-- TestModel
| |-- __init__.py
| |-- admin.py
| |-- models.py
| |-- tests.py
testdb.py代碼:
from django.http import HttpResponse from TestModel.models import Test # 數據庫操作
def testdb(request): #添加數據
test1 = Test(name='w3cschool.cc') test1.save() # 通過objects這個模型管理器的all()獲得所有數據行,相當於SQL中的SELECT * FROM
list = Test.objects.all() # filter相當於SQL中的WHERE,可設置條件過濾結果
response0 = Test.objects.filter(id=1) # 獲取單個對象
response1 = Test.objects.get(id=1) return HttpResponse("<p>數據庫操作成功!</p>")
5.修改urls.py文件並發布
from django.conf.urls import url from project_example import view from project_example import search from project_example import testdb urlpatterns = [ url(r'user1/$', view.user1), url(r'user2/$', view.user2), url(r'search-post/$', search.search_post), url(r'testdb/$', testdb.testdb), ]
發布:python manage.py runserver 0.0.0.0:8000
七、嘗試了一些簡單例子之后,回顧理解Django結構
Django主要分為三部分:模板、模型、表單
模板:表現邏輯部分,就是上述的view.py文件,主要負責Web開發中展現的頁面內容。在App開發中應該就是邏輯運算部分,名字就不用view了。
模型:數據存取邏輯,也就是數據庫操作那部分。
表單:業務邏輯,對應着urls.py文件,根據用戶傳來的數據決定調用模板中的哪些函數來處理。
