看我多久能學(xué)會Django(二):視圖與網(wǎng)址

本文章來自自強學(xué)堂:http://www.ziqiangxuetang.com/django/django-tutorial.html

Django中網(wǎng)址是寫在urls.py文件中阔蛉,用正則表達式對應(yīng)views.py中的一個函數(shù)(或者generic類),來個小栗子癞埠。

第一步:新建項目(project)状原,項目名字:mysite

django-admin startproject  mysite 

運行成功后,我們看下目錄結(jié)構(gòu):

.
├── manage.py
└── mysite
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

1 directory, 5 files

我們會發(fā)現(xiàn)執(zhí)行命令后苗踪,新建了一個 mysite 目錄颠区,其中還有一個 mysite 目錄,這個子目錄 mysite 中是一些項目的設(shè)置 settings.py 文件通铲,總的urls配置文件 urls.py 以及部署服務(wù)器時用到的 wsgi.py 文件毕莱, init.py 是python包的目錄結(jié)構(gòu)必須的,與調(diào)用有關(guān)测暗。

我們在外層的mysite目錄下創(chuàng)建應(yīng)用(app)

第二步:新建一個應(yīng)用(app)央串,名稱learn

python manage.py  startapp   learn 

我們可以看到mysite中多個一個 learn 文件夾,其中有以下文件碗啄。

# tree  learn 
learn
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│   └── __init__.py
├── models.py
├── tests.py
└── views.py

1 directory, 7 files

把我們新定義的app加到settings.py中的INSTALL_APPS中
修改 mysite/mysite/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
 
    'learn',
]

注意:新建的 app 如果不加到 INSTALL_APPS 中的話, django 就不能自動找到app中的模板文件(app-name/templates/下的文件)和靜態(tài)文件(app-name/static/中的文件)

第三步:定義視圖函數(shù)(訪問頁面時的內(nèi)容)

我們在learn這個目錄中,把views.py打開,修改其中的源代碼,改成下面的

  #coding:utf-8
  from django.shortcuts import render
  
  # Create your views here.
  from  django.http import HttpResponse
  
  def index(request):
      return HttpResponse(u'你好质和,Django')

聲明編碼為utf-8, 因為我們在代碼中用到了中文,如果不聲明就報錯.

引入HttpResponse,它是用來向網(wǎng)頁返回內(nèi)容的稚字,就像Python中的 print 一樣饲宿,只不過 HttpResponse 是把內(nèi)容顯示到網(wǎng)頁上。

我們定義了一個index()函數(shù)胆描,第一個參數(shù)必須是 request瘫想,與網(wǎng)頁發(fā)來的請求有關(guān),request 變量里面包含get或post的內(nèi)容昌讲,用戶瀏覽器国夜,系統(tǒng)等信息在里面

第四步:定義視圖函數(shù)相關(guān)的URL(網(wǎng)址) (即規(guī)定 訪問什么網(wǎng)址對應(yīng)什么內(nèi)容)

我們打開 mysite/mysite/urls.py 這個文件, 修改其中的代碼:

 from django.conf.urls import url
 from django.contrib import admin
 from learn import views as learn_views
 
 
 urlpatterns = [
     url(r'^$',learn_views.index),
     url(r'^admin/', admin.site.urls),
 ]

在終端上運行 python manage.py runserver 我們會看到類似下面的信息:

Performing system checks...

System check identified no issues (0 silenced).

You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
March 02, 2017 - 20:08:48
Django version 1.10.5, using settings 'mysite.settings'
Starting development server at http://0.0.0.0:8000/
Quit the server with CTRL-BREAK.

結(jié)果:

Paste_Image.png

Django 視圖與網(wǎng)址進階

栗子一:在網(wǎng)頁上做加減法

1,采用 /add/?a=4&b=5

django-admin   startproject  addtest
cd  addtest
python manage.py  startapp  addapp

上面的步驟創(chuàng)建了項目并且添加了app短绸,我們看下目錄結(jié)構(gòu):

# tree   addtest/
addtest/
├── addapp
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── addtest
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-35.pyc
│   │   └── settings.cpython-35.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

4 directories, 14 files

首先修改settings.py文件车吹,將我們的app加入INSTALLED_APPS。
接著修改addapp/views.py文件:

from django.shortcuts import render

from django.http import HttpResponse

# Create your views here.

def add(request):
    a = request.GET['a']
    b = request.GET['b']
    c = int(a)+int(b)
    return  HttpResponse(str(c))

最后修改addtest/urls.py

from addapp import  views as views_add

urlpatterns = [
    url(r'^add/$',views_add.add,name='add'),
    url(r'^admin/', admin.site.urls),
]

運行程序醋闭,并在瀏覽器中輸入:http://127.0.0.1:8000/add/ 就可以看到

Paste_Image.png

之所以這樣窄驹,是因為我們并沒有傳值進去,當(dāng)我們在鏈接后面加上?a=4&b=5证逻,即訪問 http://127.0.0.1:8000/add/?a=4&b=5

Paste_Image.png

當(dāng)我們改變a和b的值的時候乐埠,結(jié)果會隨之改變。

栗子二:采用/add/3/4/ 這樣的網(wǎng)址的方式

首先,我們修改addapp/views.py丈咐,添加一個新的函數(shù)add2():

from django.shortcuts import render

from django.http import HttpResponse

# Create your views here.

def add(request):
    a = request.GET['a']
    b = request.GET['b']
    c = int(a)+int(b)
    return  HttpResponse(str(c))

def add2(request,a,b):
    c = int(a)+int(b)
    return  HttpResponse(str(c))

然后修改addtest/urls.py

from addapp import  views as views_add

urlpatterns = [
    url(r'^add/$',views_add.add,name='add'),
    url(r'^add/(\d+)/(\d+)/$',views_add.add2,name='add2'),  #修改了之一行
    url(r'^admin/', admin.site.urls),
]

我們可以看到網(wǎng)址中多了 (\d+), 正則表達式中 \d 代表一個數(shù)字瑞眼,+ 代表一個或多個前面的字符,寫在一起 \d+ 就是一個或多個數(shù)字扯罐,用括號括起來的意思是保存為一個子組负拟,每一個子組將作為一個參數(shù),被views.py中的對應(yīng)視圖函數(shù)接收歹河。

運行之后掩浙,訪問 http://127.0.0.1:8000/add/3/4/ 結(jié)果為:

Paste_Image.png

Django URL name詳解

在上面的urls.py中 url(r'^add/(\d+)/(\d+)/$',views_add.add2,name='add2'),這里的name是用來做什么的呢秸歧?
簡單的講厨姚,name可以用在templates,models键菱,views ......中得到對應(yīng)的網(wǎng)址谬墙,相當(dāng)于給網(wǎng)址起了個名字,只要名字不變经备,網(wǎng)址變了也能通過名字獲取到拭抬。

什么鬼,還是不明白侵蒙,看看栗子吧造虎,首先新建一個首頁的視圖和url

1,修改addapp/views.py

from django.shortcuts import render

from django.http import HttpResponse

# Create your views here.
def index(request):
    return render(request,'home.html') #render是渲染模板

還有之前我們已經(jīng)做過的纷闺,把addapp加到settings.py 中算凿。這樣,使用render的時候犁功,Django 會自動找到 INSTALLED_APPS 中列出的各個 app 下的 templates 中的文件氓轰。

2,新建templates文件

我們在addapp中新建一個templates文件夾浸卦,在templates中新建一個home.html
在home.html中寫入以下內(nèi)容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Django</title>
</head>
<body>
<a href="/add/4/5">計算4+5</a>
</body>
</html>

接著修改urls.py:

from addapp import  views as views_add

urlpatterns = [
    url(r'^$',views_add.index,name='home'),
    url(r'^add/$',views_add.add,name='add'),
    url(r'^add/(\d+)/(\d+)/$',views_add.add2,name='add2'),
    url(r'^admin/', admin.site.urls),
]

最后我們運行程序署鸡,在瀏覽器中訪問 http://127.0.0.1:8000/ 可以看到:

Paste_Image.png

我們計算加法的時候用的是 /add/4/5/ ,后來需求發(fā)生變化限嫌,比如改成 /4_add_5/靴庆,但在網(wǎng)頁中,代碼中很多地方都寫死的 /add/4/5/萤皂,比如模板中可能是這么寫的 :

<a href="/add/4/5/">計算 4+5</a>

如果這樣寫“死網(wǎng)址”撒穷,會使得在改了網(wǎng)址(正則)后匣椰,模板(template)裆熙,視圖(views.py,用以用于跳轉(zhuǎn)),模型(models.py入录,可以用用于獲取對象對應(yīng)的地址)用了此網(wǎng)址的蛤奥,都得進行相應(yīng)的更改。

下面我們討論僚稿,如何修改這種問題:
首先我們先說一下如何用 Python 代碼獲取對應(yīng)的網(wǎng)址(可以用在 views.py凡桥,models.py等各種需要轉(zhuǎn)換得到網(wǎng)址的地方):

from django.urls import reverse
>>> reverse('add2', args=(4,5))
u'/add/4/5/'
>>> reverse('add2', args=(444,555))
u'/add/444/555/'

reverse接收url中的name作為第一個參數(shù),我們在代碼中可以通過reverse()來獲取對應(yīng)的網(wǎng)址(這個網(wǎng)址可以用來跳轉(zhuǎn)蚀同,也可以用來計算相關(guān)頁面的地址缅刽,只要對應(yīng)的url的name不變,就不用改變代碼中的網(wǎng)址蠢络。

在網(wǎng)頁模板中可以方便的使用:

不帶參數(shù)的:
{% url 'name' %}
帶參數(shù)的:參數(shù)可以是變量名
{% url 'name' 參數(shù) %}
 
例如:
<a href="{% url 'add2' 4 5 %}">link</a>

上面代碼渲染成的最終頁面是:

<a href="/add/4/5/">link</a>

這樣就可以通過 {% url 'add2' 4 5 %} 獲取到對應(yīng)的網(wǎng)址 /add/4/5/

當(dāng) urls.py 進行更改衰猛,前提是不改 name(這個參數(shù)設(shè)定好后不要輕易改),獲取的網(wǎng)址也會動態(tài)地跟著變刹孔,比如改成:

url(r'^new_add/(\d+)/(\d+)/$',views_add.add2,name='add2'),

注意看重點 add 變成了 new_add啡省,但是后面的 name='add2' 沒改,這時 {% url 'add2' 4 5 %} 就會渲染對應(yīng)的網(wǎng)址成 /new_add/4/5/

用在 views.py 或 models.py 等地方的 reverse函數(shù)髓霞,同樣會根據(jù) name 對應(yīng)的url獲取到新的網(wǎng)址卦睹。

想要改網(wǎng)址的時候,修改 urls.py 中的正則表達式部分(url 參數(shù)第一部分)方库,name 不變的前提下结序,其它地方都不需要修改。

如果用戶收藏夾中收藏的URL是舊的薪捍,如何讓以前的 /add/3/4/自動跳轉(zhuǎn)到現(xiàn)在新的網(wǎng)址呢笼痹?

具體思路是,在 views.py 寫一個跳轉(zhuǎn)的函數(shù):

from django.http import HttpResponseRedirect   #注意這行是新增的
from django.shortcuts import render

from django.http import HttpResponse
from django.urls import reverse                           #注意這行是新增的

# Create your views here.
def old_add2_redirect(request,a,b):
    return  HttpResponseRedirect(
        reverse('add2',args=(a,b))
    )

在urls.py中:

urlpatterns = [
    url(r'^$',views_add.index,name='home'),
    url(r'^add/(\d+)/(\d+)/$',views_add.old_add2_redirect),
    url(r'^new_add/(\d+)/(\d+)/$',views_add.add2,name='add2'),
    url(r'^admin/', admin.site.urls),
]

這樣就能解決:假如用戶收藏夾中有 /add/4/5/ 酪穿,訪問時就會自動跳轉(zhuǎn)到新的 /new_add/4/5/ 了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凳干,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子被济,更是在濱河造成了極大的恐慌救赐,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件只磷,死亡現(xiàn)場離奇詭異经磅,居然都是意外死亡,警方通過查閱死者的電腦和手機钮追,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門预厌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人元媚,你說我怎么就攤上這事轧叽∶绮祝” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵炭晒,是天一觀的道長待逞。 經(jīng)常有香客問我,道長网严,這世上最難降的妖魔是什么识樱? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮震束,結(jié)果婚禮上怜庸,老公的妹妹穿的比我還像新娘。我一直安慰自己垢村,他們只是感情好休雌,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肝断,像睡著了一般杈曲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胸懈,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天担扑,我揣著相機與錄音,去河邊找鬼趣钱。 笑死涌献,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的首有。 我是一名探鬼主播燕垃,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼井联!你這毒婦竟也來了卜壕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤烙常,失蹤者是張志新(化名)和其女友劉穎轴捎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚕脏,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡侦副,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了驼鞭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秦驯。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖挣棕,靈堂內(nèi)的尸體忽然破棺而出译隘,到底是詐尸還是另有隱情葱蝗,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布细燎,位于F島的核電站,受9級特大地震影響皂甘,放射性物質(zhì)發(fā)生泄漏玻驻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一偿枕、第九天 我趴在偏房一處隱蔽的房頂上張望璧瞬。 院中可真熱鬧,春花似錦渐夸、人聲如沸嗤锉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘟忱。三九已至,卻和暖如春苫幢,著一層夾襖步出監(jiān)牢的瞬間访诱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工韩肝, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留触菜,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓哀峻,卻偏偏與公主長得像涡相,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子剩蟀,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容