iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 22
0
Modern Web

From Django 1.11 to Django 2.1 系列 第 22

Day22 : Django urls name

Day 20 ,我們學會了如何透過 path() 來動態的產生更多的網址

但在實作上,我們知道網路位址為只在哪,但是使用者並不曉得!

因此我們可以在前端網頁加上超連結,讓使用這可以透過連結到其他頁面

這裡先示範 hard code 的寫法

# vendor template 底下的 detail.html
{% extends "base.html" %}
{% block title %} My store {% endblock %}
{% block content%}
{% for vlist in vendor_list %}
  <h1> 店家 : {{vlist.vendor_name}} </h1>
  <p> <a href="/vendor/{{vlist.id}}"> More detail...</a> </p>
{% endfor %}
{% endblock %}

# 對應 views 的 showtemplate
def showtemplate(request):
    vendor_list = Vendor.objects.all()
    context = {'vendor_list': vendor_list}
    # print(vendor_list)
    return render(request, 'vendors/detail.html', context)

另一種方法則是,我們都知道 vlist 參數是一個物件,也就是透過 Model - Vendor 所創建出來的,因此我們能在該 Model 下創建一個函式,也就是說

class Vendor(models.Model):
	vendor_name = models.CharField(max_length = 20) # 攤販的名稱
	store_name = models.CharField(max_length = 10) # 攤販店家的名稱
	phone_number = models.CharField(max_length = 20) # 攤販的電話號碼
	address = models.CharField(max_length = 100) # 攤販的地址
    
    # 新增
	def get_absolute_url(self):
		return f"/vendor/{self.id}/"
        
# 並將 detail.html 修改如下
{% extends "base.html" %}
{% block title %} My store {% endblock %}
{% block content%}
{% for vlist in vendor_list %}
  <h1> 店家 : {{vlist.vendor_name}} </h1>
  <p> <a href= {{ vlist.get_absolute_url }}> More detail...</a> </p>
{% endfor %}
{% endblock %}

之後下 python manage.py runserver,上面這兩種方法,你都能夠看到這樣的頁面
https://ithelp.ithome.com.tw/upload/images/20181022/20111829fwfLMS1vCV.jpg

雖然這樣能夠成功完成我們要的功能,不過千萬不要這麼做!! 這會讓你之後維護到 咪咪帽帽

因此,今天要告訴大家的方法是,大家如果還有印象,我們撰寫 urlspatterns 時,會有一個 name 的欄位

# 回顧 urls.py
urlpatterns = [
    path('', views.showtemplate),
    path('<int:id>/', views.singleVendor, name='vendor_id'), # 這一行
    path('create', views.vendor_create_view),
    path('fcreate', views.food_create_view),
]

這一個 name 的概念就是,為這一個 path 命名,也就是說以後在別的地方使用這一個名稱 vendor_id,再將其反轉換 reverse(),便能夠方便的讓我們命名以及維護一個網址

那我們要如何操作呢?

讓我們延用剛剛定義的 get_absolute_url 吧!

from django.urls import reverse # 新增

# 將 get_absolute_url 修改如下
	def get_absolute_url(self):
		return reverse("vendor_id", kwargs={"id": self.id})

第一個參數要擺的便是我們定義的 urls name - vendor_id,且因為在 urlspattern 裡面有規定要吃一個 整數 id,因此後方則是要將額外的參數 (kwargs) 一起帶進這一個 reverse() 函式

urlpatterns = [
    path('<int:id>/', views.singleVendor, name='vendor_id'),
    ...略
]

你說這樣子的寫的好處在哪,好處就是 今天需要修改網址位址,只要修改 urlspattern 即可,也就是說

# 我在 網址前方多加了 haha
urlpatterns = [
    path('haha<int:id>/', views.singleVendor, name='vendor_id'),
    ...略
]

超連結的後方也會自動加上 haha!
https://ithelp.ithome.com.tw/upload/images/20181022/20111829h7bS7G9xTd.jpg

因為此時此刻,我們得到網址的方法是跟著 path name 綁定,所以 只要 不動到 <int:id> , Django 會動態的幫你處理超連結綁定的工作唷! 就再也不會因為 hard code 而苦惱拉 ^^"


今天小節

我們今天談到了 path 裡面的 name 如何結合 reverse 來達到 動態網址的效果,不再因為 hard-coded 的方式而讓你苦惱,reverse 可以傳入的參數不只是 kwargs, args 也可以,這部分就留給大家去研究囉!

今天講到這,我們明天見 ^^

import this ... the zen of Python!


上一篇
Day 21 : 網頁例外
下一篇
Day23 : Django 命名空間
系列文
From Django 1.11 to Django 2.1 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
to790303
iT邦新手 5 級 ‧ 2019-07-27 20:04:29

您好,跟著文章實作已經可以做到顯示more detail超連結的部分,但是超連結過去,會顯示TypeError at /vendor/1/這樣的錯誤訊息,請問是哪裡沒有設置好嗎? 謝謝

Lee iT邦新手 5 級 ‧ 2019-08-10 15:14:24 檢舉

第一個方法我可以正常顯示及超連結過去,但是第二個我的terminal畫面會一直顯示return f"/vendor/{self.id}/" 不合法,不知道是它打錯還是我哪邊有誤(我這邊先跳過)

我要留言

立即登入留言