Django控制器
配置路由
通過對urls.py的配置將用戶請求映射到處理函數。
Django的URL字符串匹配實際上基于正則表達式,這允許單條URL可以匹配一類請求。參見Django Book中的示例:
from django.conf.urls import urlfrom . import viewsurlpatterns = [url(r'^articles/2003/$', views.special_case_2003),url(r'^articles/([0-9]{4})/$', views.year_archive),url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), ]實例解析:
/articles/2005/03/請求將匹配列表中的第三個模式。Django 將調用函數views.month_archive(request, '2005', '03');無論如何匹配,匹配的內容均將作為Python字符串傳遞給視圖函數。
/articles/2005/3/ 不匹配任何URL 模式,因為列表中的第三個模式要求月份應該是兩個數字。
/articles/2003/ 將匹配列表中的第一個模式不是第二個,因為模式按順序匹配,第一個會首先測試是否匹配。請像這樣自由插入一些特殊的情況來探測匹配的次序。
/articles/2003 不匹配任何一個模式,因為每個模式要求URL以一個反斜線結尾。
在Python 正則表達式中,命名正則表達式組的語法是(?Ppattern),其中name 是組的名稱,pattern 是要匹配的模式。
from django.conf.urls import urlfrom . import viewsurlpatterns = [url(r'^articles/2003/$', views.special_case_2003),url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), ]以命名組的語法重寫上述代碼,兩者區別在于捕獲的值作為關鍵字參數而不是位置參數傳遞給視圖函數
/articles/2005/03/ 請求將調用views.month_archive(request, year='2005', month='03')函數,而不是views.month_archive(request, '2005', '03')。
針對正則表達式中的命名組和非命名組,如果有命名參數url解析器將使用命名參數,否則將以位置參數傳遞所有匹配的字符串。
進行匹配時將不包括GET或POST請求方式的參數以及域名:
http://www.example.com/myapp/
http://www.example.com/myapp/?page=3
對同一個URL的無論是POST請求、GET請求、或HEAD請求方法都將映射到相同的函數。
urlpatterns 中的每個正則表達式在第一次訪問它們時被編譯。這使得系統相當快。
使用include
urlpatterns可以包含另一URLConf模塊:
from django.conf.urls import include, urlurlpatterns = [# ... snip ...url(r'^community/', include('django_website.aggregator.urls')),url(r'^contact/', include('django_website.contact.urls')),# ... snip ... ]注意,這個例子中的正則表達式沒有包含$(字符串結束匹配符),但是包含一個末尾的反斜杠.
每當Django 遇到django.conf.urls.include()時,它會去掉URL 中匹配的部分并將剩下的字符串發送給包含的URLconf 做進一步處理。
from django.conf.urls import include, urlfrom apps.main import views as main_views from credit import views as credit_viewsextra_patterns = [url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),url(r'^charge/$', credit_views.charge), ]urlpatterns = [url(r'^$', main_views.homepage),url(r'^help/', include('apps.help.urls')),url(r'^credit/', include(extra_patterns)), ]在這個例子中,URL/credit/reports/將被credit.views.report()這個函數處理。
編寫views函數
views函數接受封裝了HTTP請求的request對象作為參數, 返回response對象作為HTTP響應.
若返回str對象, django會將其封裝為response對象, 也可以返回模板渲染結果或者redirect對象.
django.http.JsonResponse將一個dict對象構造為JSON格式的響應:
`return JsonResponse({'result': 'ok'})`使用模板
編寫hello.py并保存在templates下:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Hello</title> </head> <body><p>{{ hello }}</p> </body> </html>修改HelloWorld/settings.py,修改 TEMPLATES 中的 DIRS:'DIRS': [os.path.join(BASE_DIR, 'templates')]。
修改 view.py,增加一個新的對象,用于向模板提交數據:
from django.shortcuts import renderdef hello(request):context = {}context['hello'] = 'Hello World'return render(request, 'hello.html',context)render函數原形:
render(request, template_name[, context][, content_type][, status][, using])[source]
render(渲染)通常使用3個位置參數:
render(request, template_name, context = None)分別為HttpRequest對象,模板文件名和上下文詞典并返回一個渲染后的 HttpResponse 對象。模板引擎可以在上下文context中搜索對象并進行渲染。
可選參數:
content_type:生成的文檔要使用的MIME 類型。默認為DEFAULT_CONTENT_TYPE 設置的值。
status: 響應的狀態碼,默認為200.
using用于加載模板使用的模板引擎的名稱.如:
'django.template.backends.django.DjangoTemplates'
'django.template.backends.jinja2.Jinja2'
render方法返回響應字符串,render_to_response則返回HttpResponse對象。
def hello(request):context = dict()response = render_to_response('test-cookies.html', context)return response重定向
重定向將對某一URL的請求,轉到另外的URL。
Django中常用3中方法實現頁面重定向。
在模板視圖函數中使用redirect()
一般情況下redirect()接受一個絕對或相對URL的字符串,并返回一個臨時重定向。
關鍵字參數permanent的默認值為False,傳入permanent=True則可以返回一個永久重定向。
from django.shortcuts import redirectdef hello(request):return redirect(r'^admin/')在URL配置中使用redirect_to
配置ulrs.py
from django.conf.urls import url from django.contrib import admin from FirstDjango.view import hello from django.views.generic.base import RedirectViewurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^hello/', hello),url(r'^world/', RedirectView.as_view(url='/hello/')) ]訪問127.0.0.1/world/的效果等同于訪問127.0.0.1/hello/。
使用redirects app進行重定向
在settings.py 中 增加 'django.contrib.redirects' 到你的 INSTALLED_APPS 設置。
增加 'django.contrib.redirects.middleware.RedirectFallbackMiddleware' 到的MIDDLEWARE_CLASSES 設置中。
運行 manage.py syncdb. 創建 django_redirect 表,包含 site_id, old_path and new_path 字段。
獲得請求參數
HTTP方法用于表示用戶提交請求的動作類型, 常用的有GET和POST方法.
Django將HTTP請求封裝為request, 我們可以從中獲得請求參數等信息.
Django的URL匹配不區分請求方法,不對請求參數進行匹配,對同一個URL的不同方法的請求將會映射到同樣的處理函數.但是我們可以通過request對象獲得HTTP方法的信息.
GET方法
GET方法會將請求參數包含在URL中,一般用于發送獲取而不改變服務器數據的請求。
GET方法適合發送搜索查詢等請求,因為數據被保存在URL中可以方便地作為書簽,分享或重新提交。
HttpRequest.GET屬性是一個封裝了GET請求參數的dict,只需要在詞典中訪問響應的參數即可。
form-get.html:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><form action="/search-post/" method="get"><input type="text" name="search_content"><input type="submit" value="submit"></form><p>{{ result }}</p></body> </html>search.py:
def search_get(request):context = dict()if 'search_content' in request.GET:context['result'] = request.GET['search_content']return render(request, 'form-post.html', context)urls.py:
from django.conf.urls import url from django.contrib import admin from SecondDjango.views import *urlpatterns = [url(r'^admin/', admin.site.urls),url(r'form-get/', search),url(r'^search-get', search_get), ]POST方法
POST方法是更常用的提交數據的方法,它常用來提交要求改變服務器狀態的請求如登錄請求.
Django為POST方法提供了CSRF保護,這只需要在模板中添加csrf_token即可。
HttpRequest.POST屬性是一個封裝了除file_upload相關參數外POST請求參數的dict,只需要在詞典中訪問響應的參數即可。因為可能存在空參數的情況,所以要先進行相關校驗。
form-post.html:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body><form action="/search-post/" method="post">{% csrf_token %}<input type="text" name="search_content"><input type="submit" value="submit"></form><p>{{ result }}</p></body> </html>與form-get.html相比,多了{% csrf_token %}用來提供和csrf保護。
search.py:
from django.shortcuts import render from django.core.context_processors import csrf# Create your views here.def search(request):return render(request, 'form-post.html', None)def search_get(request):context = dict()if 'search_content' in request.GET:context['result'] = request.GET['search_content']return render(request, 'form-post.html', context)urls.py:
from django.conf.urls import url from django.contrib import admin from SecondDjango.views import *urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^form-post/', search),url(r'^search-post/', search_post), ]文件上傳
Django上傳文件的內容包含在HttpResponse.FILE中。
編寫file-upload.html:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>File Upload</title> </head> <body><form action="/handle-upload/" method="post" enctype="multipart/form-data">{% csrf_token %}<input type="file" name="file"><br><br><input type="submit" value="upload"></form> </body> </html>編寫file-upload-success.html:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>File Upload Success</title> </head> <body><p>{{ filename }} uploaded successfully</p> </body> </html>編寫views.py:
def handle_upload(request):print('handling upload')file = request.FILES['file']filename = str(request.FILES['file'])print(filename)if not os.path.exists('upload/'):os.mkdir('upload/')out = open('upload/' + filename, 'wb+')for chunk in file.chunks():out.write(chunk)print('write finished')# render responsecontext = dict()context['filename'] = filenamereturn render(request, 'file-upload-success.html', context)def upload(request):return render(request, 'file-upload.html')配置urls.py:
from django.conf.urls import url from django.contrib import admin from SecondDjango.views import *urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^handle-upload/', handle_upload),url(r'^upload/', upload), ]session 與 cookie
Http協議是無狀態協議,以請求-響應的模式工作用戶不保持在線狀態。session和cookie是用來保持對用戶跟蹤的常用方法。
cookies
cookies是保存在客戶端硬盤上的小文件,瀏覽器在發送請求時會將cookies包含在HttpRequest中一同發送。
服務端可以在HttpResponse中重新設置cookies, 瀏覽器收到cookies之后會自動更新保存在客戶端硬盤上的cookie文件。
編寫test-cookies.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Test Cookies</title> </head> <body>尹大人被打了{{ num }}次了!{{ beat }} </body> </html>編寫views.py
def test_cookies(request):context = dict()if 'num' in request.COOKIES:num = int(request.COOKIES['num']) + 1else:num = 1beat = ''for i in range(num+1):beat += '啊!'context['num'] = str(num)context['beat'] = beatresponse = render_to_response('test-cookies.html', context)response.set_cookie('num', str(num))return response因為要使用response.set_cookie所以采用render_to_response渲染。
配置urls.py
from django.conf.urls import url from django.contrib import admin from SecondDjango.views import *urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^test-cookies/', test_cookies), ]session
session(會話)對象是保存了追蹤用戶信息的詞典,一般情況下若瀏覽器未關閉或未超時session將會有效.
session使用cookie在客戶端保存用于識別用戶的token, 數據保留在服務端.
Django提供了基于緩存、文件和數據庫的session引擎, 若要啟動session首先在settings.py中進行配置.
修改 MIDDLEWARE_CLASSES 設置,并確定其中包含了 'django.contrib.sessions.middleware.SessionMiddleware'
修改INSTALLED_APPS設置,確定其中包含了 django.contrib.sessions
默認情況下以上兩個設置為支持session的狀態。此外還需設置session引擎SESSION_ENGINE
默認為基于數據庫的引擎django.contrib.sessions.backends.db
基于文件的引擎django.contrib.sessions.backends.file
這里采用最簡單的基于緩存的引擎django.contrib.sessions.backends.cache
編寫login-session.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Login Session</title> </head> <body><form action="/login-validate/" method="post">{% csrf_token %}<input type="text" name="username"><input type="password" name="password"><input type="submit" value="submit"></form></body> </html>編寫login-success.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Login Success</title> </head> <body><p>Welcome, {{ current_user }}!</p> </body> </html>編寫keep-online.html
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Keep Online</title> </head> <body><p>{{ username }}, you are still online.</p> </body> </html>編寫views.py
def login(request):return render(request, 'login-session.html')def login_validate(request):context = dict()if request.POST['password'] == 'exciting':request.session['current_user'] = 'NaiveUser'context['current_user'] = request.session['current_user']return render(request, 'login-success.html', context)def keep_online(request):context = dict();context['username'] = request.session['current_user']return render(request, 'keep-online.html', context)可以方便的對HttpRequest.session進行操作,然后使用render將其渲染到HttpResponse中返回客戶端。
配置urls.py
from django.conf.urls import url from django.contrib import admin from SecondDjango.views import *urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^login-session/', login),url(r'^login-validate/', login_validate),url(r'^keep-online/', keep_online), ]訪問127.0.0.1:8000/login-session/輸入"NaiveUser","exciting"登錄。在關閉瀏覽器之前訪問127.0.0.1:8000/keep-online/,可以看到:
訪問127.0.0.1:8000/test-cookies/,然后再次發送請求(刷新)。可以發現服務器跟蹤了訪問的次數。
轉載于:https://www.cnblogs.com/Finley/p/5255584.html
總結
- 上一篇: swift - if let Optio
- 下一篇: HDU ACM 1078 FatMous