Django URL


一、創建Django項目:

用命令行創建:

創建項目:在終端通過命令:django-admin startproject [項目名稱] 即可創建,比如:django-admin startproject fisher_django

創建應用:在終端進入到項目所在的路徑,然后執行python manage.py startapp [app名稱] 即可創建一個app

pycharm創建

pycharm創建項目后,需重新進入到命令行創建app

project和app的關系:

app是django項目的組成部分,一個app代表項目中的一個模塊,所有URL請求的響應都是由app來處理

django項目由多個app組成,一個app可以被用到其他項目

項目結構介紹:

manage.py:和項目交互的文件,python manage.py [子命令],可通過python manage.py help查看幫助

settings.py:項目的設置項

urls.py:配置URL路由

wsgi.py:項目與WSGI協議兼容的web服務器入口,用於項目部署

運行Django項目:

python manage.py runserver,默認端口8000

指定端口號python manage.py runserver 9000

需在其它電腦訪問本站,python manage.py runserver 0.0.0.0:8000

也可通過pycharm運行

二、視圖與URL分發器

URL分發器

視圖:

視圖一般都寫在appviews.py中。並且視圖的第一個參數永遠都是request(一個HttpRequest)對象。這個對象存儲了請求過來的所有信息,包括攜帶的參數以及一些頭部信息等。在視圖中,一般是完成邏輯相關的操作。比如這個請求是添加一篇博客,那么可以通過request來接收到這些數據,然后存儲到數據庫中,最后再把執行的結果返回給瀏覽器。視圖函數的返回結果必須是HttpResponseBase對象或者子類的對象。示例代碼如下:

from django.http import HttpResponse def book_list(request): return HttpResponse("書籍列表!") 

URL映射:

視圖寫完后,要與URL進行映射,也即用戶在瀏覽器中輸入什么url的時候可以請求到這個視圖函數。在用戶輸入了某個url,請求到我們的網站的時候,django會從項目的urls.py文件中尋找對應的視圖。在urls.py文件中有一個urlpatterns變量,以后django就會從這個變量中讀取所有的匹配規則。匹配規則需要使用django.urls.path函數進行包裹,這個函數會根據傳入的參數返回URLPattern或者是URLResolver的對象。示例代碼如下:

from django.contrib import admin from django.urls import path from book import views urlpatterns = [ path('admin/', admin.site.urls), path('book/',views.book_list) ] 

URL中添加參數:

有時候,url中包含了一些參數需要動態調整。比如簡書某篇文章的詳情頁的url,是https://www.jianshu.com/p/a5aab9c4978e后面的a5aab9c4978e就是這篇文章的id,那么簡書的文章詳情頁面的url就可以寫成https://www.jianshu.com/p/<id>,其中id就是文章的id。那么如何在django中實現這種需求呢。這時候我們可以在path函數中,使用尖括號的形式來定義一個參數。比如我現在想要獲取一本書籍的詳細信息,那么應該在url中指定這個參數。示例代碼如下:

from django.contrib import admin from django.urls import path from book import views urlpatterns = [ path('admin/', admin.site.urls), path('book/',views.book_list), path('book/<book_id>/',views.book_detail) ] 

views.py中的代碼如下:

def book_detail(request,book_id): text = "您輸入的書籍的id是:%s" % book_id return HttpResponse(text) 

當然,也可以通過查詢字符串的方式傳遞一個參數過去。示例代碼如下:

urlpatterns = [
    path('admin/', admin.site.urls), path('book/',views.book_list), path('book/detail/',views.book_detail) ] 

views.py中的代碼如下:

def book_detail(request): book_id = request.GET.get("id") text = "您輸入的書籍id是:%s" % book_id return HttpResponse(text) 

以后在訪問的時候就是通過/book/detail/?id=1即可將參數傳遞過去。

URL中包含另外一個urls模塊:

在我們的項目中,不可能只有一個app,如果把所有的appviews中的視圖都放在urls.py中進行映射,肯定會讓代碼顯得非常亂。因此django給我們提供了一個方法,可以在app內部包含自己的url匹配規則,而在項目的urls.py中再統一包含這個appurls。使用這個技術需要借助include函數。示例代碼如下:

# first_project/urls.py文件: from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path('book/',include("book.urls")) ] 

urls.py文件中把所有的和book這個app相關的url都移動到app/urls.py中了,然后在first_project/urls.py中,通過include函數包含book.urls,以后在請求book相關的url的時候都需要加一個book的前綴。

# book/urls.py文件: from django.urls import path from . import views urlpatterns = [ path('list/',views.book_list), path('detail/<book_id>/',views.book_detail) ] 

以后訪問書的列表的url的時候,就通過/book/list/來訪問,訪問書籍詳情頁面的url的時候就通過book/detail/<id>來訪問。

path函數:

path函數的定義為:path(route,view,name=None,kwargs=None)。以下對這幾個參數進行講解。

  1. route參數:url的匹配規則。這個參數中可以指定url中需要傳遞的參數,比如在訪問文章詳情頁的時候,可以傳遞一個id。傳遞參數是通過<>尖括號來進行指定的。並且在傳遞參數的時候,可以指定這個參數的數據類型,比如文章的id都是int類型,那么可以這樣寫<int:id>,以后匹配的時候,就只會匹配到idint類型的url,而不會匹配其他的url,並且在視圖函數中獲取這個參數的時候,就已經被轉換成一個int類型了。其中還有幾種常用的類型:

    • str:非空的字符串類型。默認的轉換器。但是不能包含斜杠。
    • int:匹配任意的零或者正數的整形。到視圖函數中就是一個int類型。
    • slug:由英文中的橫杠-,或者下划線_連接英文字符或者數字而成的字符串。
    • uuid:匹配uuid字符串。
    • path:匹配非空的英文字符串,可以包含斜杠。
  2. view參數:可以為一個視圖函數或者是類視圖.as_view()或者是django.urls.include()函數的返回值。

  3. name參數:這個參數是給這個url取個名字的,這在項目比較大,url比較多的時候用處很大。

  4. kwargs參數:有時候想給視圖函數傳遞一些額外的參數,就可以通過kwargs參數進行傳遞。這個參數接收一個字典。傳到視圖函數中的時候,會作為一個關鍵字參數傳過去。比如以下的url規則:

     from django.urls import path from . import views urlpatterns = [ path('blog/<int:year>/', views.year_archive, {'foo': 'bar'}), ] 

    那么以后在訪問blog/1991/這個url的時候,會將foo=bar作為關鍵字參數傳給year_archive函數。

re_path函數:

有時候我們在寫url匹配的時候,想要寫使用正則表達式來實現一些復雜的需求,那么這時候我們可以使用re_path來實現。re_path的參數和path參數一模一樣,只不過第一個參數也就是route參數可以為一個正則表達式。
一些使用re_path的示例代碼如下:

    from django.urls import path, re_path from . import views urlpatterns = [ path('articles/2003/', views.special_case_2003), re_path(r'articles/(?P<year>[0-9]{4})/', views.year_archive), re_path(r'articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/', views.month_archive), re_path(r'articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-_]+)/', views.article_detail), ] 

以上例子中我們可以看到,所有的route字符串前面都加了一個r,表示這個字符串是一個原生字符串。在寫正則表達式中是推薦使用原生字符串的,這樣可以避免在python這一層面進行轉義。而且,使用正則表達式捕獲參數的時候,是用一個圓括號進行包裹,然后這個參數的名字是通過尖括號<year>進行包裹,之后才是寫正則表達式的語法。

include函數:

在項目變大以后,經常不會把所有的url匹配規則都放在項目的urls.py文件中,而是每個app都有自己的urls.py文件,在這個文件中存儲的都是當前這個app的所有url匹配規則。然后再統一注冊到項目的urls.py文件中。include函數有多種用法,這里講下兩種常用的用法。

  1. include(pattern,namespace=None):直接把其他appurls包含進來。示例代碼如下:

     from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path('book/',include("book.urls")) ] 

    當然也可以傳遞namespace參數來指定一個實例命名空間,但是在使用實例命名空間之前,必須先指定一個應用命名空間。示例代碼如下:

    # 主urls.py文件: from django.urls import path,include urlpatterns = [ path('movie/',include('movie.urls',namespace='movie')) ] 

    然后在movie/urls.py中指定應用命名空間。實例代碼如下:

    from django.urls import path from . import views # 應用命名空間 app_name = 'movie' urlpatterns = [ path('',views.movie,name='index'), path('list/',views.movie_list,name='list'), ] 
  2. include(pattern_list):可以包含一個列表或者一個元組,這個元組或者列表中又包含的是path或者是re_path函數。

  3. include((pattern,app_namespace),namespace=None):在包含某個appurls的時候,可以指定命名空間,這樣做的目的是為了防止不同的app下出現相同的url,這時候就可以通過命名空間進行區分。示例代碼如下:

     from django.contrib import admin from django.urls import path,include urlpatterns = [ path('admin/', admin.site.urls), path('book/',include(("book.urls",'book')),namespace='book') ] 

    但是這樣做的前提是已經包含了應用命名空間。即在myapp.urls.py中添加一個和urlpatterns同級別的變量app_name

指定默認的參數:

使用path或者是re_path的后,在route中都可以包含參數,而有時候想指定默認的參數,這時候可以通過以下方式來完成。示例代碼如下:

from django.urls import path from . import views urlpatterns = [ path('blog/', views.page), path('blog/page<int:num>/', views.page), ] # View (in blog/views.py) def page(request, num=1): # Output the appropriate page of blog entries, according to num. ... 

當在訪問blog/的時候,因為沒有傳遞num參數,所以會匹配到第一個url,這時候就執行view.page這個視圖函數,而在page函數中,又有num=1這個默認參數。因此這時候就可以不用傳遞參數。而如果訪問blog/1的時候,因為在傳遞參數的時候傳遞了num,因此會匹配到第二個url,這時候也會執行views.page,然后把傳遞進來的參數傳給page函數中的num

url反轉:

之前我們都是通過url來訪問視圖函數。有時候我們知道這個視圖函數,但是想反轉回他的url。這時候就可以通過reverse來實現。示例代碼如下:

reverse("list") > /book/list/ 

如果有應用命名空間或者有實例命名空間,那么應該在反轉的時候加上命名空間。示例代碼如下:

reverse('book:list') > /book/list/ 

如果這個url中需要傳遞參數,那么可以通過kwargs來傳遞參數。示例代碼如下:

reverse("book:detail",kwargs={"book_id":1}) > /book/detail/1 

因為django中的reverse反轉url的時候不區分GET請求和POST請求,因此不能在反轉的時候添加查詢字符串的參數。如果想要添加查詢字符串的參數,只能手動的添加。示例代碼如下:

login_url = reverse('login') + "?next=/" 

自定義URL轉換器:

之前已經學到過一些django內置的url轉換器,包括有intuuid等。有時候這些內置的url轉換器並不能滿足我們的需求,因此django給我們提供了一個接口可以讓我們自己定義自己的url轉換器。

自定義url轉換器按照以下五個步驟來走就可以了:

  1. 定義一個類。
  2. 在類中定義一個屬性regex,這個屬性是用來保存url轉換器規則的正則表達式。
  3. 實現to_python(self,value)方法,這個方法是將url中的值轉換一下,然后傳給視圖函數的。
  4. 實現to_url(self,value)方法,這個方法是在做url反轉的時候,將傳進來的參數轉換后拼接成一個正確的url。
  5. 將定義好的轉換器,注冊到django中。

比如寫一個匹配四個數字年份的url轉換器。示例代碼如下:

    # 1. 定義一個類 class FourDigitYearConverter: # 2. 定義一個正則表達式 regex = '[0-9]{4}' # 3. 定義to_python方法 def to_python(self, value): return int(value) # 4. 定義to_url方法 def to_url(self, value): return '%04d' % value # 5. 注冊到django中 from django.urls import register_converter register_converter(converters.FourDigitYearConverter, 'yyyy') urlpatterns = [ path('articles/2003/', views.special_case_2003), # 使用注冊的轉換器 path('articles/<yyyy:year>/', views.year_archive), ... ] 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM