Django - - - -视图层之视图函数(views)
閱讀目錄(Content)
- 視圖層之視圖函數(views)
- 一個簡單的視圖
- 1.HttpRequest
- 2.HttpResponse
- ?1.render 函數
- ?2.redirect 函數
- 對比render與redirect:
回到頂部(go to top)
視圖層之視圖函數(views)
一個視圖函數,簡稱視圖,是一個簡單的Python 函數,它接受Web請求并且返回Web響應。響應可以是一張網頁的HTML內容,一個重定向,一個404錯誤,一個XML文檔,或者一張圖片. . . 是任何東西都可以。無論視圖本身包含什么邏輯,都要返回響應。代碼寫在哪里也無所謂,只要它在你的Python目錄下面。除此之外沒有更多的要求了——可以說“沒有什么神奇的地方”。為了將代碼放在某處,約定是將視圖放置在項目或應用程序目錄中的名為views.py的文件中。
?
視圖函數:
??? 一定包含兩個對象:
?? ???? requset---->用戶請求相關的所有信息(對象)
?? ??? ?Httpresponse---->響應字符串
一個簡單的視圖
下面是一個返回當前日期和時間作為HTML文檔的視圖:
from django.http import HttpResponse import datetimedef current_datetime(request):now = datetime.datetime.now()html = "<html><body>It is now %s.</body></html>" % nowreturn HttpResponse(html)讓我們逐行閱讀上面的代碼:
-
首先,我們從?django.http模塊導入了HttpResponse類,以及Python的datetime庫。
-
接著,我們定義了current_datetime函數。它就是視圖函數。每個視圖函數都使用HttpRequest對象作為第一個參數,并且通常稱之為request。
注意,視圖函數的名稱并不重要;不需要用一個統一的命名方式來命名,以便讓Django識別它。我們將其命名為current_datetime,是因為這個名稱能夠精確地反映出它的功能。
-
這個視圖會返回一個HttpResponse對象,其中包含生成的響應。每個視圖函數都負責返回一個HttpResponse對象。
?
視圖函數,圍繞著兩個對象進行:HttpResponse和HttpRequest
1.HttpRequest
request---->請求信息
?
屬性:
request.path # 獲取訪問文件路徑request.method屬性 #獲取請求中使用的HTTP方式(POST/GET)request.body #含所有請求體信息 是bytes類型request.GET #GET請求的數據(類字典對象) 請求頭中的url中?后面拿值 request.POST # POST請求的數據(類字典對象) 請求體里拿值request.COOKIES #包含所有cookies的標準Python字典對象;keys和values都是字符串。 request.FILES: 包含所有上傳文件的類字典對象;FILES中的每一個Key都是<input type="file" name="" />標簽中name屬性的值,FILES中的每一個value同時也是一個標準的python字典對象,包含下面三個Keys:filename: 上傳文件名,用字符串表示content_type: 上傳文件的Content Typecontent: 上傳文件的原始內容request.user: 是一個django.contrib.auth.models.User對象,代表當前登陸的用戶。如果訪問用戶當前沒有登陸,user將被初始化為django.contrib.auth.models.AnonymousUser的實例。你可以通過user的is_authenticated()方法來辨別用戶是否登陸:if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware時該屬性才可用request.session: 唯一可讀寫的屬性,代表當前會話的字典對象;自己有激活Django中的session支持時該屬性才可用request.GET.get('name')? 拿到GET請求里name的值如果某個鍵對應有多個值,則不能直接用get取值,需要用getlist,如:request.POST.getlist("hobby") 請求url:http://127.0.0.1:8000/index.html/23?a=1request.path : 請求路徑?? ??? request.path結果為:/index.html/23request.get_full_path()request.get_full_path()結果為:/index.html/23?a=1?
方法:
| 1 | get_full_path() |
注意:鍵值對的值是多個的時候,比如checkbox類型的input標簽,select標簽,需要用:
| 1 | request.POST.getlist("hobby") |
?
2.HttpResponse
HttpResponse---->相應字符串
對于HttpRequest請求對象來說,是由django自動創建的,但是,HttpResponse響應對象就必須我們自己創建。每個view請求處理方法必須返回一個HttpResponse響應對象。HttpResponse類在django.http.HttpResponse。
在HttpResponse對象上擴展的常用方法
?1.render 函數
將指定頁面渲染后返回給瀏覽器
render(request, template_name[, context])
結合一個給定的模板和一個給定的上下文字典,并返回一個渲染后的 HttpResponse 對象。
參數:request: 用于生成響應的請求對象。template_name:要使用的模板的完整名稱,可選的參數context:添加到模板上下文的一個字典。默認是一個空字典。如果字典中的某個值是可調用的,視圖將在渲染模板之前調用它。content_type:生成的文檔要使用的MIME類型。默認為DEFAULT_CONTENT_TYPE 設置的值。status:響應的狀態碼。默認為200。 from django.shortcuts import renderdef test(request):return render(request,'index.html') #向用戶顯示一個html頁面下面為render官方源碼,可以看出render最后也是返回了一個HttpResponse給webserver
def render(request, template_name, context=None, content_type=None, status=None, using=None):"""Returns a HttpResponse whose content is filled with the result of callingdjango.template.loader.render_to_string() with the passed arguments."""content = loader.render_to_string(template_name, context, request, using=using)return HttpResponse(content, content_type, status)細說render:
render方法主要是將從服務器提取的數據,填充到模板中,然后將渲染后的html靜態文件返回給瀏覽器。這里一定要注意:render渲染的是模板,下面我們看看什么叫作模板:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title><style>li,ul,ol{ list-style: none; }a{ text-decoration: none; }</style> </head> <body> <ul>{% for book in list %}<li><a href="{{book.id}}">{{ book.btitle }}</a></li>{% endfor %} </ul> </body> </html>?
上面{%%}之間包括的就是我們要從數據庫取出的數據,進行填充。對于這樣一個沒有填充數據的html文件,瀏覽器是不能進行渲染的,所以,對于上述{%%}之間的內容先要被render進行渲染之后,才能發送給瀏覽器。
下面舉個例子:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Title</title><style>li,ul,ol{ list-style: none; }a{ text-decoration: none; }</style> </head> <body> <ul>{% for book in list %}<li><a href="{{book.id}}">{{ book.btitle }}</a></li>{% endfor %}</ul> </body> </html>show.html
def show(request, id): book = BookInfo.objects.get(pk=id) #從數據庫中取出對應id的數據herolist = book.heroinfo_set.all() context = {'list': herolist} # 將數據保存在listreturn render(request, 'booktest/show.html', context) #通過render進行模板渲染?
?
?2.redirect 函數
參數可以是:
- 一個模型:將調用模型的get_absolute_url()?函數
- 一個視圖,可以帶有參數:將使用urlresolvers.reverse?來反向解析名稱
- 一個絕對的或相對的URL,將原封不動的作為重定向的位置。
默認返回一個臨時的重定向;傳遞permanent=True?可以返回一個永久的重定向。
示例:
你可以用多種方式使用redirect()?函數。
傳遞一個對象
將調用get_absolute_url()?方法來獲取重定向的URL:
| 1 2 3 4 5 6 | from?django.shortcuts?import?redirect ? def?my_view(request): ????... ????object?=?MyModel.objects.get(...) ????return?redirect(object) |
傳遞一個視圖的名稱
可以帶有位置參數和關鍵字參數;將使用reverse()?方法反向解析URL:
| 1 2 3 | def?my_view(request): ????... ????return?redirect('some-view-name', foo='bar') |
傳遞要重定向的一個硬編碼的URL
| 1 2 3 | def?my_view(request): ????... ????return?redirect('/some/url/') |
也可以是一個完整的URL:
| 1 2 3 | def?my_view(request): ????... ????return?redirect('http://example.com/') |
默認情況下,redirect()?返回一個臨時重定向。以上所有的形式都接收一個permanent?參數;如果設置為True,將返回一個永久的重定向:
| 1 2 3 4 | def?my_view(request): ????... ????object?=?MyModel.objects.get(...) ????return?redirect(object, permanent=True) |
跳轉(重定向)應用
-----------------------------------url.pyurl(r"login", views.login),url(r"yuan_back", views.yuan_back),-----------------------------------views.py def login(req):if req.method=="POST":if 1:# return redirect("/yuan_back/")name="yuanhao"return render(req,"my backend.html",locals())return render(req,"login.html",locals())def yuan_back(req):name="苑昊"return render(req,"my backend.html",locals())-----------------------------------login.html<form action="/login/" method="post"><p>姓名<input type="text" name="username"></p><p>性別<input type="text" name="sex"></p><p>郵箱<input type="text" name="email"></p><p><input type="submit" value="submit"></p> </form> -----------------------------------my backend.html <h1>用戶{{ name }}你好</h1>View Code
?
?
下面我們來看一個現象:
--------------------urls.py------------------------------urlpatterns = [url(r'^admin/', admin.site.urls),url(r'^login/', views.login),url(r'^index/', views.index,),# url(r'^register/', views.register,name='reg'),]------------------view.py------------------------------- def login(request):if request.method=='POST':username=request.POST.get('user')password=request.POST.get('pwd')if username=='yuan' and password=='123':# return render(request,'index.html')return redirect('/index/')else:return render(request,'login.html',{'info':'賬號或密碼錯誤'})else:return render(request,'login.html')def index(request):name='yuan'return render(request,'index.html',{'a':name})---------------login.html-------------------------------- <h1>登陸界面</h1> <form action="/login/" method="post"><p>姓名 <input type="text" name="user"></p><p>密碼 <input type="password" name="pwd"></p><p><input type="submit"></p><p>{{ info }}</p> </form>---------------login.html-------------------------------- <h1>個人主頁</h1> <h2>hello,{{ a}}</h2>代碼
?
首先,啟動服務器后,我們進入login頁面
?
正確輸入姓名,密碼后,此時執行redirect函數,結果如下
現在我們將redirect換成render,再重新走一遍看看,在login頁面,正確輸入姓名,密碼后,結果如下:
細心的人會發現,用render函數執行后的,地址欄的地址沒有變化,還是login,且頁面上的{{a}}此時也沒有被渲染,所以hello,后面沒有內容顯示!
對比render與redirect:
原因是
??????? render: 只是返回頁面內容,但是未發送第二次請求
??????? redirect:發送了第二次請求,url更新
?
?
?
?
總結兩者區別:
第一,render返回一個登陸成功后的頁面,刷新該頁面將回復到跳轉前頁面。而redirect則不會
? 第二,如果頁面需要模板語言渲染,需要的將數據庫的數據加載到html,那么render方法則不會顯示這一部分,render返回一個登陸成功頁面,不會經過url路由分發系統,也就是說,不會執行跳轉后url的視圖函數。這樣,返回的頁面渲染不成功;而redirect是跳轉到指定頁面,當登陸成功后,會在url路由系統進行匹配,如果有存在的映射函數,就會執行對應的映射函數。
?
https://www.cnblogs.com/huchong/p/7718393.html
總結
以上是生活随笔為你收集整理的Django - - - -视图层之视图函数(views)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python mysql in 参数_p
- 下一篇: 血的案例告诫 | 模拟大批量数据测试边界