Django 是用 Python 寫的一個自由和開放源碼 web 應用程序框架。
web框架是一套組件,能幫助你更快、更容易地開發web站點。當你開始構建一個web站點時,你總需要一些相似的組件:處理用戶認證(注冊、登錄、登出)的方式、一個管理站點的面板、表單、上傳文件的方式,等等。
有很多人注意到web開發人員會面臨一些共同的問題,他們聯手創建了 web 框架(Django 是其中一個)來供人使用。框架的存在,你無需重新發明輪子就能建立新的站點。
本篇使用的是Django 1.11, windows系統。文中的示例源碼已經上傳到github: django快速入門源碼。
1 創建django工程
打開命令行,cd 到一個你想放置你代碼的目錄,然后運行以下命令:
django-admin startproject mysite
示例:

這行代碼將會在當前目錄下創建一個 mysite 目錄。mysite目錄只是你項目的名稱, Django 不關心它的名字,可以將它重命名為任何你喜歡的名字。
2 運行django
命令行中CD到你創建的工程中,我這里是mysite目錄,輸入以下命令:
python manage.py runserver
這樣創建的網站就開始運行了,django啟動默認端口為8000,可以用瀏覽器訪問:http://127.0.0.1:8000/,如下:

這樣說明django程序成功運行起來了。
3 Django工程目錄詳解
接下來用pycharm打開我們的mysite目錄,可以看到以下目錄結構:

這些文件或目錄的作用:
(1)最外層的mysite/目錄: 是項目的容器, Django 不關心它的名字,可以將它重命名其他名字。
(2)manage.py: 一個讓你用各種方式管理 Django 項目的命令行工具。比如我們之前用的python manage.py runserver命令。
(3)里面一層的mysite/目錄:包含你的項目,它是一個純 Python 包。它的名字就是當你引用它內部任何東西時需要用到的 Python 包名。 比如 mysite.urls。
(4)mysite/__init__.py: 一個空文件,告訴 Python 這個目錄應該被認為是一個 Python 包。
(5)mysite/settings.py:Django 項目的配置文件。后面會詳細說到。
(6)mysite/urls.py:Django 項目的 URL 路由系統,就像你網站的“目錄”。
(7)mysite/wsgi.py:作為你的項目的運行在 WSGI 兼容的Web服務器上的入口。后面會詳細說到。
(8)db.sqlite3 是django默認使用的sqlite3數據庫文件。
4 開始一個app
接下來我們創建app目錄(用於寫整個web站點的某種功能),命令如下:
python manage.py startapp app01
(1) 編寫視圖
在app01/views.py 中寫如下函數:
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, welcome to app01 index.")
(2)在mysite/urls.py中聲明一個路由
from django.conf.urls import url
from django.contrib import admin
from app01 import views # 導入app01的視圖
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index', views.index), # 注冊index 路由
]
需要做兩點:導入視圖,注冊路由。 然后我們重啟服務,訪問http://127.0.0.1:8000/index/看看:
重啟服務:

訪問http://127.0.0.1:8000/index/:

這樣我們就完成了第一個視圖頁面。
5 CBV和FBV
(1)function based view (FBV)。
像前文那樣在app01/views.py 中,寫一個函數,處理請求,並返回結果就叫function based view,簡稱FBV。我們可以寫的詳盡些:
app01/views.py中:
from django.http import HttpResponse
# function base views
def home(request):
ret = None
if request.method == "GET":
ret = "Welcome to home."
return HttpResponse(ret)
mysite/urls.py中:
from app01 import views # 導入app01的視圖
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^home', views.home), # 注冊home 路由
]
重啟之后訪問:http://127.0.0.1:8000/home,如下:

注意:視圖函數中的request是django對http請求的封裝,其中request.method封裝了請求動作,包括GET,PUT,POST等。
(2)class based view (CBV)
用類代替視圖函數的方法就叫做CBV,寫法如下:
app01/views.py中:
from django.http import HttpResponse
from django.views import View # 引入該類
# class based view
class MyHome(View): # 繼承views類
def get(self, request): # get請求會用這個方法處理,如果是post請求再寫個post方法處理即可
ret = "Welcome to my home"
return HttpResponse(ret)
mysite/urls.py中:
from django.conf.urls import url
from app01 import views # 導入app01的視圖
urlpatterns = [
# 注冊myhome 路由, 方式是views.類名.as_view()
url(r'^myhome', views.MyHome.as_view()),
]
重啟服務之后,訪問:http://127.0.0.1:8000/myhome, 如下:

有時可以在類中通過繼承父類的despatch方法,然后做一些自定義操作。如下:
# class based view
class MyHome(View):
def dispatch(self, request, *args, **kwargs):
# 調用父類中的dispatch
print('before')
result = super(MyHome, self).dispatch(request, *args, **kwargs)
print('after')
return result
def get(self, request):
ret = "Welcome to my home"
return HttpResponse(ret)
想知道CBV的更多原理,可以去看下源碼。
6 使用模板
(1)返回html字符串
前文演示了在視圖函數中直接返回一些字符串給用戶,用的是from django.http import HttpResponse中的HttpResponse對象。
還可以用from django.shortcuts import HttpResponse 的HttpResponse是一樣的,我們稍加改編一下返回的字符串,改成帶有HTML標簽的字符串看看:
from django.shortcuts import HttpResponse
def index(request):
ret = "<h1>{}</h1>".format("Hello, welcome to app01 index.")
return HttpResponse(ret)
重啟之后,訪問http://127.0.0.1:8000/index,如下:

可見,我們的“<h1></h1>” 標簽是生效的,也就是說,如果我們把一個HTML文件的內容讀取成一長串字符串的返回,那么用戶就能看到一個完整的網頁了。
在Python中,往往把HTML文件統一放在templates目錄下。
(2)在項目根目錄mysite下新建templates文件夾

(3)然后,在django的配置文件mysite/settings.py中找到TEMPLATES這個變量,是一個大列表,在列表中的DIRS后面,配上'templates',即可;即'DIRS': ['templates', ],如下:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['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',
],
},
},
]
(4)接下來可以在templates文件夾下創建一個HTML文件,如index.html

index.html文件內容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首頁</title>
</head>
<body>
<h1>Welcome to mysite index..</h1>
<a href="http://www.cnblogs.com/zingp/">博客連接</a>
</body>
</html>
(5)在app01/views.py中修改一下視圖函數index()
from django.shortcuts import render
def index(request):
return render(request, "index.html",)
(6)重啟后,訪問http://127.0.0.1:8000/index

7 使用模板語言
(1)views.py 的index中可以傳變量,如下
def index(request):
name = "liuyy"
fruits = ["火龍果", "香蕉", "西瓜"]
info = {
"age": 26,
"salary": 1000000,
}
return render(request, "index.html", {"name": name, "fruits": fruits, "user": info})
(2)傳參數之后可以在模板index.html中使用這些參數
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首頁</title>
</head>
<body>
<h1>Welcome to mysite index..</h1>
<a href="http://www.cnblogs.com/zingp/">博客連接</a>
<p>我是{{ name }}</p>
<p>喜歡的水果有:</p>
{% for item in fruits %}
<p>水果{{ forloop.counter }}: {{ item }}</p>
{% endfor %}
{% if "age" not in user %}
<p>沒有年齡</p>
{% else %}
<p> 年齡 {{ user.age }}</p>
{% endif %}
<p> 第二個水果 {{ fruits.1 }}</p>
{% for k, v in user.items %}
<p>{{ k }}: {{ v }}</p>
{% endfor %}
</body>
</html>
重啟之后,訪問http://127.0.0.1:8000/index,如下:

總結一下模板語言格式:
# 單個變量{{ name }}
# if else 語句
{% if 條件 %}
dosth..
{% else %}
dosth..
{% endif %}
# 遍歷item_list
{% for item in item_list %}
<p>{{ item }}</p>
{% endfor %}
# 表示第幾次循環(從1開始): {{ forloop.counter }}
# 如果是第一次循環{{ forloop.first }}為True, 否則為 False
# 如果是最后一次循環 {{ forloop.last }} 為True, 否則為False
# 遍歷字典dic
{% for k, v in user.items %}
<p>{{ k }}: {{ v }}</p>
{% endfor %}
# 列表li中的第i個元素: {{ li.i }}
# 字典dic中k對應的值: {{ dic.k }}
# 使用繼承模板:
# 母板base.html:{% block title %} {% endblock %}
# 子板:{% extends "base.html" %}
{% block title %} {% endblock %}
# 幫助方法:
{{ item.timetype|date:"Y-m-d H:i:s"}}
{{ bio|truncatewords:"30" }}
{{ my_list|first|upper }}
{{ name|lower }}
8 自定義simple_tag
(1)在app01目錄下創建templatetags目錄
(2)在templatetags目錄下新建任意py文件, 如tag1.py

並且在tag1.py中這樣寫:
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
@register.simple_tag
def tag_add_3_no(v1, v2, v3):
return v1 + v2 + v3
@register.simple_tag
def my_input(name):
result = "<h1> %s </h1>" % name
# mark_safe 會讓html標簽合法
return mark_safe(result)
其中的兩個函數就是自己自定義的函數,想怎么寫怎么寫。
(3) 哪個html文件需要引用自定義的simple_tag,需要在html中導入之前創建的py文件
{% load tag1 %}
(4)在html模板中使用simple_tag
{% tag_add_3_no 1 2 3%}
{% my_input '我的simpletag'%}
即{% 函數名 參數1 參數2%}
(5)關鍵一步:在settings.py中配置app
找到settings中的INSTALLED_APPS,注冊app01,如下:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',
]
如果不注冊的話,django無法找到自定義的simple_tag。
為方便我們新創建了一個simple.html以及視圖函數simple, 並新注冊了路由:
simple.html:
{% load tag1 %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>simple</title>
</head>
<body>
<p> {% tag_add_3_no 1 2 3%} </p>
{% my_input '我的simpletag'%}
</body>
</html>
views:
def simple(request):
return render(request, "simple.html")
urls:
url(r'^simple', views.simple),
重啟服務,訪問http://127.0.0.1:8000/simple,如下:

