Django的get_absolute_url方法的使用
本文主要的目的是通過(guò)一個(gè)簡(jiǎn)單的例子,展示`get_absolute_url`的用法,拋磚引玉,理解實(shí)例方法的本質(zhì),能夠在不同的業(yè)務(wù)場(chǎng)景下,靈活多變,完成需求。
環(huán)境:Python3.8 + Django3.0
我們都知道,在反向解析url的時(shí)候,Django提供了三種方法,幫我們替代硬編碼的方式,也就是:
- 在模板中:使用
url
模板標(biāo)簽。 - 在Python代碼中:使用
reverse()
函數(shù)。 - 在更高層的與處理Django模型實(shí)例相關(guān)的代碼中:使用
get_absolute_url
方法。
前面兩種方式比較常見(jiàn),我們也很熟悉,但是最后的get_absolute_url
方法,可能很多人就不明白具體如何使用了。下面我們通過(guò)一個(gè)簡(jiǎn)單易懂的例子,來(lái)搞懂它的具體使用方法。
一、創(chuàng)建模型
首先,假設(shè)我們有下面的學(xué)生模型:
class Student(models.Model): sex_choice = [ ('man', '男性'), ('woman', '女性'), ] name = models.CharField(max_length=128) sex = models.CharField(max_length=8, choices=sex_choice) tel = models.PositiveIntegerField() def __str__(self): return self.name
學(xué)生包含姓名、性別和電話。
不要忘記makemigrations和migrate。
然后我們接入admin后臺(tái),隨意手動(dòng)創(chuàng)建一些學(xué)生實(shí)例:
from django.contrib import admin from app.models import Student class StudentAdmin(admin.ModelAdmin): list_display = ['name', 'sex', 'tel'] admin.site.register(Student, StudentAdmin)
二、設(shè)計(jì)urls
我們編寫(xiě)了下面的urls:
from django.contrib import admin from django.urls import path from app import views urlpatterns = [ path('admin/', admin.site.urls), path('students/', views.students), path('man/<int:id>/', views.man, name='man'), path('woman/<int:id>/', views.woman, name='woman'), ]
這里的students比較好理解,查看所有的學(xué)生列表。但是man和woman兩條路由的設(shè)計(jì)就屬于特殊需求了,按理說(shuō)應(yīng)該直接一條路由即可,不就是查看某個(gè)具體學(xué)生的信息嘛。
但如果業(yè)務(wù)需求是這樣的:男生和女生必須使用不同的url進(jìn)行訪問(wèn)!
那就只能這么分開(kāi)編寫(xiě)成兩條路由了。
注意url中的name屬性,用于后面的反向路由解析。
三、編寫(xiě)視圖
我們編寫(xiě)了下面的視圖,很簡(jiǎn)單:
from django.shortcuts import render from app import models def students(request): s = models.Student.objects.all() return render(request, 'students.html', locals()) def man(request, id): student = models.Student.objects.get(id=id) return render(request, 'student.html', locals()) def woman(request, id): student = models.Student.objects.get(id=id) return render(request, 'student.html', locals())
四、HTML模板
首先看看student.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p>name: {{ student.name }}</p> <p>sex: {{ student.sex }}</p> <p>tel: {{ student.tel }}</p> </body> </html>
很簡(jiǎn)單,就是展示學(xué)生的信息,沒(méi)有需要關(guān)注的,僅僅用于表示運(yùn)行正常,信息顯示正確。
重點(diǎn)是students.html
(多了個(gè)s,復(fù)數(shù)形式):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h4>歡迎訪問(wèn)liujiangblog.com, 學(xué)習(xí)更多Django教程</h4> {% for student in s %} {% if student.sex == 'man' %} <p> 姓名:{{ student.name }} 詳情:<a href="{% url 'man' student.id %}" rel="external nofollow" >{% url 'man' student.id %}</a> </p> {% else %} <p> 姓名:{{ student.name }} 詳情:<a href="{% url 'woman' student.id %}" rel="external nofollow" >{% url 'woman' student.id %}</a> </p> {% endif %} {% endfor %} </body> </html>
通過(guò)if標(biāo)簽的判斷,決定最終生成的url是哪種。這里使用了Django內(nèi)置的url模板標(biāo)簽語(yǔ)法。
訪問(wèn)students/
頁(yè)面顯示結(jié)果:
點(diǎn)擊任何一條學(xué)生鏈接都可以正常跳轉(zhuǎn)到詳情頁(yè)面。
五、使用get_absolute_url方法
上面的代碼實(shí)現(xiàn)了業(yè)務(wù)需求,男生和女生自動(dòng)生成了不一樣的url,而不是我們慣例的/student/
,整個(gè)過(guò)程也很簡(jiǎn)單,比較好理解。
但是,這里有個(gè)不足之處,那就是區(qū)分男女生的邏輯放在了HTML模板文件中,這不是個(gè)好的做法,也不優(yōu)雅。
實(shí)際上我們可以使用get_absolute_url
方法,在Python代碼中實(shí)現(xiàn)這一功能。
首先,修改Student模型,添加get_absolute_url
方法:
class Student(models.Model): sex_choice = [ ('man', '男性'), ('woman', '女性'), ] name = models.CharField(max_length=128) sex = models.CharField(max_length=8, choices=sex_choice) tel = models.PositiveIntegerField() def __str__(self): return self.name def get_absolute_url(self): from django.urls import reverse if self.sex == 'man': return reverse('man', args=(self.id,)) else: return reverse('woman', args=(self.id,))
在get_absolute_url
方法中,我們導(dǎo)入了reverse,這是Django提供的反向解析功能。
reverse能避免我們對(duì)url進(jìn)行硬編碼,它接收多種類型的參數(shù),可以是一個(gè)視圖名,也可以是一個(gè)url的name。相關(guān)的參數(shù)通過(guò)args傳遞,這是一個(gè)元組,有順序。
上面的代碼中,通過(guò)if/else判斷,根據(jù)性別的不同,解析出男女生對(duì)應(yīng)的url。
然后,在students.html
中,我們就可以修改成下面的樣子:
<body> <h4>歡迎訪問(wèn)liujiangblog.com, 學(xué)習(xí)更多Django教程</h4> {% for student in s %} <p> 姓名:{{ student.name }} 詳情:<a href="{{ student.get_absolute_url }}" rel="external nofollow" >{{ student.get_absolute_url }}</a> </p> {% endfor %} </body>
首先,沒(méi)有if/else模板標(biāo)簽了。其次使用{{ student.get_absolute_url }}
來(lái)代替url模板標(biāo)簽。
student是Student模型類的一個(gè)實(shí)例,它可以訪問(wèn)類中定義的get_absolute_url方法,從而進(jìn)入if/else判斷,然后根據(jù)性別的不同,reverse出不同的url字符串,并在HTML模板中展示出來(lái)。
整個(gè)HTML模板顯得更加簡(jiǎn)潔優(yōu)雅,最后的頁(yè)面結(jié)果也是完全一樣的。實(shí)際上,這里也體現(xiàn)出了Django的模型層和模板層的高度配合。
六、總結(jié)思考
例子很簡(jiǎn)單,無(wú)非就是在Student模型中添加了一個(gè)get_absolute_url
方法。但是如果仔細(xì)思考一下我們會(huì)發(fā)現(xiàn)這里面有很多體現(xiàn)語(yǔ)言特點(diǎn)的東西:
Django本身沒(méi)有實(shí)現(xiàn)一個(gè)基本的get_absolute_url
方法,在models.Model
中也沒(méi)有get_absolute_url
方法的影子,所以這個(gè)方法其實(shí)只是個(gè)思路,沒(méi)有實(shí)質(zhì)。
get_absolute_url
方法本質(zhì)上只是一個(gè)類的實(shí)例方法,既然Django內(nèi)部的代碼沒(méi)有實(shí)現(xiàn)它,那么實(shí)際上我們可以給它任意命名,比如改成get_url
。你可以試試,它絕對(duì)能正常工作。但要小心的是,Django核心源碼雖然沒(méi)有定義get_absolute_url
方法,在admin后臺(tái)和feed框架等地方卻可能使用了這個(gè)get_absolute_url
方法,所以在非必須時(shí),不要修改這個(gè)方法名。
繼續(xù)拓展思維,既然可以自定義get_absolute_url
方法,那我可不可以在模型中添加任何我需要的實(shí)例方法呢?當(dāng)然可以!并且這是最強(qiáng)大最靈活的方式!比如根據(jù)用戶的不同,為模型添加一個(gè)user_control
方法,提供不同的信息,控制訪問(wèn)權(quán)限,切換頁(yè)面主題等等。
到此這篇關(guān)于Django的get_absolute_url方法的使用的文章就介紹到這了,更多相關(guān)Django get_absolute_url方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python rsa實(shí)現(xiàn)數(shù)據(jù)加密和解密、簽名加密和驗(yàn)簽功能
本篇文章主要說(shuō)明python庫(kù)rsa生成密鑰對(duì)數(shù)據(jù)的加密解密,api接口的簽名和驗(yàn)簽功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2019-09-09Python中函數(shù)調(diào)用9大方法小結(jié)
在Python中,函數(shù)是一種非常重要的編程概念,它們使得代碼模塊化、可重用,并且能夠提高代碼的可讀性,本文將深入探討Python函數(shù)調(diào)用的9種方法,需要的可以參考下2024-01-01python網(wǎng)絡(luò)編程示例(客戶端與服務(wù)端)
這篇文章主要介紹了python網(wǎng)絡(luò)編程示例,提供了客戶端與服務(wù)端,需要的朋友可以參考下2014-04-04python matplotlib如何給圖中的點(diǎn)加標(biāo)簽
這篇文章主要介紹了python matplotlib給圖中的點(diǎn)加標(biāo)簽,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11Python區(qū)塊鏈創(chuàng)世塊創(chuàng)建教程
這篇文章主要為大家介紹了Python區(qū)塊鏈創(chuàng)世塊創(chuàng)建教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05詳解Django定時(shí)任務(wù)模塊設(shè)計(jì)與實(shí)踐
這篇文章主要介紹了詳解Django定時(shí)任務(wù)模塊設(shè)計(jì)與實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Python中文分詞工具之結(jié)巴分詞用法實(shí)例總結(jié)【經(jīng)典案例】
這篇文章主要介紹了Python中文分詞工具之結(jié)巴分詞用法,結(jié)合實(shí)例形式總結(jié)分析了Python針對(duì)中文文件的讀取與分詞操作過(guò)程中遇到的問(wèn)題與解決方法,需要的朋友可以參考下2017-04-04python中[[]] * (n)和[[] for _ in 
本文主要介紹了python中[[]] * (n)和[[] for _ in range(n)]的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02