Django基礎(路由與檢視)
目錄
一、Django 簡介
Django 是一個由 Python 寫成的開放原始碼的 Web 應用框架。它最初是被開發來用於管理勞倫斯出版集團旗下的一些以新聞內容為主的網站的,即是 CMS(內容管理系統)軟體。並於2005年7月在 BSD 許可證下發布。這套框架是以比利時的吉普賽爵士吉他手 Django Reinhardt 來命名的。由於 Django 的是在一個快節奏的新聞編輯室環境下開發的,它的目的是使常見的 Web 開發任務,快速和容易。
特點
MTV 模式
Django 採用了 MTV 設計模式
上述圖大概是說:
- URL ( urls.py )請求排程,當有快取頁面的時候直接返回內容。
- 檢視函式( view.py )執行所請求的操作,通常包括讀寫資料庫。
- 模型( models.py )定義了 Python 中的資料並與之互動。通常包含在一個關係資料庫( MySQL、PostgreSQL SQLite 等),其他資料儲存是可能的( XML、文字檔案、LDAP、等)。
- 請求執行任務後,檢視返回一個 HTTP 響應物件(通常是經過資料處理的一個模板)。可選的:檢視可以儲存一個版本的 HTTP 響應物件,返回攜帶一個時間戳,來告訴瀏覽器這個檢視的更新時間。
- 模板通常返回 HTML 頁面。Django 模板語言提供了 HTML 的語法及邏輯。
二、安裝Django
# pip 安裝
pip install Django
# 克隆下載最新版本
git clone https://github.com/django/django.git
# 匯入django模組
>>> import django
>>> print(django.get_version())
三、基本配置
1、常用命令
# 檢視django版本
$ python -m django --version
# 建立專案,名為mysite
$ django-admin startproject mysite
# Django專案環境終端
$ python manage.py shell
# 建立應用程式,確保和 manage.py 是同一目錄
$ python manage.py startapp polls
# 啟動django
$ python manage.py runserver
$ python manage.py runserver 8080
$ python manage.py runserver 0.0.0.0:8000
# 執行創造模型變化遷移
$ python manage.py makemigrations
# 執行應用模型變化到資料庫
$ python manage.py migrate
# 同步資料庫
$ python manage.py syncdb
# 清空資料庫(保留空表)
$ python manage.py flush
# admin建立管理員使用者
$ python manage.py createsuperuser
# 修改使用者密碼
$ python manage.py changepassword username
注:自動重新載入 runserver,根據需要開發伺服器自動重新載入Python程式碼為每個請求。您不需要重新啟動伺服器程式碼更改生效。然而,像新增檔案某些操作不觸發重新啟動,所以你必須重新啟動在這些情況下的伺服器。
基本目錄結構及作用:
mysite/ # 專案的容器,名字隨便起
manage.py # 命令列實用工具,以各種方式與該Django專案進行互動
mysite/ # 實際的Python專案
__init__.py # 空檔案,匯入不出錯
settings.py # 這個Django專案配置
urls.py # 這個Django專案的URL宣告; 一個Django驅動網站的“目錄”
wsgi.py # 一個入口點為WSGI相容的Web伺服器,以滿足您的專案
2、配置檔案
INSTALLED_APPS = [
'django.contrib.admin', # 管理站點。
'django.contrib.auth', # 認證系統
'django.contrib.contenttypes',# 用於內容型別的框架
'django.contrib.sessions', # 會話框架
'django.contrib.messages', # 訊息框架
'django.contrib.staticfiles', # 管理靜態檔案的框架
'blog.apps.BlogConfig', #是建立應用app的名字,如果專案建立了app則必須要新增app的名字
]
2.1、資料庫
# django支援sqlite,mysql, oracle,postgresql資料庫
# django預設使用sqlite的資料庫,預設自帶sqlite的資料庫驅動 , 引擎名稱:django.db.backends.sqlite3
# 由於Django內部連線MySQL時使用的是MySQLdb模組,而python3中還無此模組,所以需要使用pymysql來代替
# 設定放置的與project同名的配置的 __init__.py檔案中
import pymysql
pymysql.install_as_MySQLdb()
# 在settings 中修改DATABASES
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'dbname', # 資料庫名稱
'USER': 'root', # 使用者名稱
'PASSWORD': 'xxx', # 密碼
'HOST': '', # IP,留空預設localhost
'PORT': '', # 埠
}
}
2.2、模板
# 在settings裡修改,放html檔案
TEMPLATE_DIRS = (
os.path.join(BASE_DIR,'templates'),
)
2.3、靜態檔案
# 在settings裡修改新增,放css,js,image等檔案
# 建立static資料夾
STATIC_URL = '/static/' # 相當於別名
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
)
# 如引用Jquery檔案,有倆種形式
1、 直接引入
2、 {% load staticfiles %}
{% static '檔名' %}
# 推薦使用第二種形式,第一條程式碼並處理引入檔案程式碼的上方
# 再每個app裡面我們可能會有多個檔案配置資訊,則可以相應的將資料夾放在app的資料夾下,並修改路徑。
複製程式碼
2.4、引入靜態檔案的注意點
# 注意1:
# 為了後端的更改不會影響前端的引入,避免造成前端大量修改
STATIC_URL = '/static/' # 引用名
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"statics"), # 實際名 ,即實際資料夾的名字
)
# django對引用名和實際名進行對映,引用時,只能按照引用名來,不能按實際名去找
# <script src="/statics/jquery-3.3.1.js"></script>
# ------error-----不能直接用,必須用STATIC_URL = '/static/':
# <script src="/static/jquery-3.3.1.js"></script>
# 注意2(statics資料夾寫在不同的app下,靜態檔案的呼叫):
STATIC_URL = '/static/'
STATICFILES_DIRS=(
('hello',os.path.join(BASE_DIR,"app01","statics")),
)
# <script src="/static/hello/jquery-3.3.1.min.js"></script>
# 注意3:
STATIC_URL = '/static/'
{% load staticfiles %}
# <script src={% static "jquery-3.3.1.min.js" %}></script>
# 注意4:
配置STATIC路徑時,記得要最後一個元組後面加逗號,不然會影響渲染
四、路由系統
1、URL 排程
URL配置(URLconf)就像Django 所支撐網站的目錄。它的本質是URL模式以及要為該URL模式呼叫的檢視函式之間的對映表;你就是以這種方式告訴Django,對於這個URL呼叫這段程式碼,對於那個URL呼叫那段程式碼。
django中的路由系統和其他語言的框架有所不同,在django中每一個請求的url都要有一條路由對映,這樣才能將請求交給對一個的view中的函式去處理。其他大部分的Web框架則是對一類的url請求做一條路由對映,從而是路由系統變得簡潔。
django最新版url預設不支援正則,標準格式:
path('admin/', admin.site.urls),
如果需要使用正則,需要匯入:re_path,使用方法:
from django.urls import path,re_path
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^test-(\d+)-(\d+)/', views.test),
path('index/', views.index),
]
來看以下示例,如何動態構造:
urlpatterns = [
path('admin/', admin.site.urls),
path('show_time/', views.show_time), #無名分組
re_path(r'article/(\d{4})$', views.article_year), #有名分組:(?p<分組名>正則語法)
]
# 引數說明
# 一個正則表示式字串
# 一個可呼叫物件,通常為一個檢視函式或一個指定檢視函式路徑的字串
# 可選的要傳遞給檢視函式的預設引數(字典形式)
# 一個可選的name引數
需要注意: url多傳了一個引數,那views函式得多接受一個引數
def show_time(requset):
# return HttpResponse("Hello")
t = time.ctime()
return render(requset,"index.html",{"t":t}) #locals()
# 對應接收值
def article_year(request,y):
return HttpResponse(y)
對應該的index.html
<h1>time:{{ t }}</h1>
2、name別名
name就是該views函式的別名
name別名要結合模板檔案來用方便管理
urls.py
urlpatterns = [
path("register",views.register,name="reg"),
]
在html檔案中引入
<form action="{% url 'reg' %}" method="post">
3、路由分發(include)
如果一個專案下有很多的app,那麼在urls.py裡面就要寫巨多的urls對映關係。這樣看起來很不靈活,而且雜亂無章。這時候就要根據不同的app來分發不同的url請求
首先,在urls.py裡寫入urls對映條目。注意要匯入include方法
from django.contrib import admin
from django.urls import path, re_path, include
from blog import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^blog/', include('blog.urls')),
]
這條關係的意思是將url為”blog/“的請求都交給blog下的urls去處理
其次,在blog下建立一個urls.py檔案,用來處理請求的url,使之與views建立對映
from django.urls import path, re_path, include
from blog import views
urlpatterns = [
re_path(r'article/(\d{4})$',views.article_year),
re_path(r'article/(?P<year>\d{4})/(?P<month>\d{2})',views.article_year_month),
re_path(r'article/(?P<year>\d{4})/(?P<month>\d{2})/\d+',views.article_year_month),
re_path(r"register",views.register,name="reg"),
1、STATIC_ROOT:在settings裡面設定,一般用來放一些公共的js,css,images等。
2、app的static資料夾,在每個app所在文夾均可以建立一個static資料夾,然後當執行collectstatic時,
python manage.py collectstatic
Django會遍歷INSTALL_APPS裡面所有app的static資料夾,將裡面所有的檔案複製到STATIC_ROOT。因此,如果你要建立可複用的app,那麼你要將該app所需要的靜態檔案放在static資料夾中。
也就是說一個專案引用了很多app,那麼這個專案所需要的css,images等靜態檔案是分散在各個app的static檔案
比較典型的是admin應用。當你要釋出時,需要將這些分散的static檔案收集到一個地方就是STATIC_ROOT。
3、STATIC檔案還可以配置STATICFILES_DIRS,指定額外的靜態檔案儲存位置。
STATIC_URL的含義與MEDIA_URL類似。
完整原始碼
五、檢視層
1、概述
client端通過http請求——去url的路由找到相應的檢視函式——觸發檢視函式——再去modes取資料——取到資料後——再通過建立模——views函式把相響應物件——返回給client最終顯示的內容
檢視檔案(views.py)在app目錄下才有
看看新建專案預設的views.py檔案的內容
from django.shortcuts import render, HttpResponse
import time
# Create your views here.
通過相應的url請求來寫不同請求的檢視函式
2、檢視函式的編寫
def show_time(requset):
# return HttpResponse("Hello")
t = time.ctime()
return render(requset,"index.html",{"t":t}) #locals()
檢視要結和url路由,models,模板檔案一起來用。
3、檢視函式的引數
第一個引數
檢視函式的引數必須是url的請求物件一般寫為request
後面及其他的引數
是url路由的分組資訊,一個引數表示一個分組,兩個引數表示兩個分組
def article_year(request,y):
return HttpResponse(y)
def article_year_month(request,year,month):
return HttpResponse("year:%s month:%s"%(year,month))
4、請求和響應物件
Django 使用請求和響應物件在系統間傳遞狀態。
當請求一個頁面時,Django 建立一個 HttpRequest
物件包含原資料的請求。然後 Django 載入適當的檢視,通過 HttpRequest
作為檢視函式的第一個引數。每個檢視負責返回一個HttpResponse
目標。
A、HttpRequest物件
HttpRequest.scheme
一個字串表示請求的方案(HTTP或HTTPS)通常
HttpRequest.path
一個字串的完整路徑的請求
HttpRequest.method
請求的HTTP方法。這是保證要大寫
if request.method == 'GET':
do_something()
elif request.method == 'POST':
do_something_else()
HttpRequest.GET
字典像包含所有給定的HTTP GET引數物件。
HttpRequest.POST
字典像包含所有給定的HTTP POST引數物件,提供請求包含表單資料。
HttpRequest.COOKIES
一個標準的Python字典,包含了所有的COOKIES,key和values都是字串
HttpRequest.FILES
字典像物件包含所有上傳的檔案。
html 標籤 <input type="file" name="" />
filename # 上傳的檔名
content_type # 上傳檔案的型別
content # 上傳檔案的內容
HttpRequest.META
一個標準的Python字典包含所有可用的HTTP頭。可用標題取決於客戶端和伺服器,但這裡是一些例子:
CONTENT_LENGTH – 請求體的長度(一個字串)。
CONTENT_TYPE – 請求體的型別。
HTTP_ACCEPT - 為響應–可以接受的內容型別。
HTTP_ACCEPT_ENCODING – 接受編碼的響應
HTTP_ACCEPT_LANGUAGE – 接受語言的反應
HTTP_HOST – 客戶端傳送的HTTP主機頭。
HTTP_REFERER – 參考頁面
HTTP_USER_AGENT – 客戶端的使用者代理字串。
QUERY_STRING – 查詢字串,作為一個單一的(分析的)字串。
REMOTE_ADDR – 客戶端的IP地址
REMOTE_HOST – 客戶端的主機名
REMOTE_USER – 使用者通過Web伺服器的身份驗證。
REQUEST_METHOD – 字串,如"GET"或"POST"
SERVER_NAME – 伺服器的主機名
SERVER_PORT – 伺服器的埠(一個字串)。
B、HttpResponse物件
對於HttpRequest物件來說,是由django自動建立的,但是,HttpResponse物件就必須我們自己建立。每個view請求處理方法必須返回一個HttpResponse物件。
在HttpResponse物件上擴充套件的常用方法:
5、render()
render(request, template_name, context=None, content_type=None, status=None, using=None)[source]
結合給定的模板與一個給定的上下文,返回一個字典HttpResponse在渲染文字物件
template_name 一個模板的使用或模板序列名稱全稱。如果序列是給定的,存在於第一個模板將被使用。
可選引數
- context 一組字典的值新增到模板中。預設情況下,這是一個空的字典。
- content_type MIME型別用於生成文件。
- status 為響應狀態程式碼。預設值為
200
- using 這個名字一個模板引擎的使用將模板。
def show_time(requset):
t = time.ctime()
return render(requset,"index.html",{"t":t}) #locals()
6、render_to_response()
render_to_response(template_name, context=None, content_type=None, status=None, using=None)[source]
這個和 render() 差不多,它不需要傳入request物件,並不推薦使用
7、redirect()
redirect(to, permanent=False, *args, **kwargs)[source]
此方法可稱之為頁面跳轉,可以得到達到某種條件時,如再登陸淘寶介面,登陸成功之後會跳轉到使用者的主介面
預設情況下,為臨時重定向;通過 permanent=True
設定永久重定向
from django.shortcuts import render, HttpResponse,redirect
def register(request_info):
if request_info.method == 'POST':
user = request_info.POST.get('user')
pwd = request_info.POST.get('pwd')
if user == 'Aaron' and pwd == '123456':
return redirect("/login/") #直接跳轉,url已經發生了變化
# return render(request,"login.html",locals())#url還是register,當你重新整理 時又回到原來的了
return HttpResponse('賬號或密碼錯誤')
return render(request_info,'register.html')
def login(request_info):
return render(request_info,'login.html')
# 在此可能會想到用render也可以再條件達成之後進行頁面的跳轉。
# 那麼倆者之間有什麼區別呢
# 1、the most important: url沒有跳轉到/login/,而是還在/register/,所以當重新整理後又得重新登入.
# locals()
它是區域性的,渲染所有的區域性變數,可以將函式內所有的變數傳遞request物件獲取到。
注意點、此時檢視函式內的變數名稱要和前端程式碼的變數名稱對應
def student(req):
student_list=["小明","小紅","老五","明明"]
return render(req,"student2.html",locals())
#student2.html
{% for student in student_list %}
<h2>學生{{ student }}</h2>
{% endfor %}
總結:
render() #頁面渲染,推薦 (很少用HttpResponse)
redirect("路徑") 例如登入跳轉
locals(): 可以直接將函式中所有的變數傳給模板