目錄
- 一、創(chuàng)建模型
- 二、設計urls
- 三、編寫視圖
- 四、HTML模板
- 五、使用get_absolute_url方法
- 六、總結(jié)思考
本文主要的目的是通過一個簡單的例子,展示`get_absolute_url`的用法,拋磚引玉,理解實例方法的本質(zhì),能夠在不同的業(yè)務場景下,靈活多變,完成需求。
環(huán)境:Python3.8 + Django3.0
我們都知道,在反向解析url的時候,Django提供了三種方法,幫我們替代硬編碼的方式,也就是:
- 在模板中:使用
url
模板標簽。
- 在Python代碼中:使用
reverse()
函數(shù)。
- 在更高層的與處理Django模型實例相關的代碼中:使用
get_absolute_url
方法。
前面兩種方式比較常見,我們也很熟悉,但是最后的get_absolute_url
方法,可能很多人就不明白具體如何使用了。下面我們通過一個簡單易懂的例子,來搞懂它的具體使用方法。
一、創(chuàng)建模型
首先,假設我們有下面的學生模型:
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
學生包含姓名、性別和電話。
不要忘記makemigrations和migrate。
然后我們接入admin后臺,隨意手動創(chuàng)建一些學生實例:
from django.contrib import admin
from app.models import Student
class StudentAdmin(admin.ModelAdmin):
list_display = ['name', 'sex', 'tel']
admin.site.register(Student, StudentAdmin)
二、設計urls
我們編寫了下面的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比較好理解,查看所有的學生列表。但是man和woman兩條路由的設計就屬于特殊需求了,按理說應該直接一條路由即可,不就是查看某個具體學生的信息嘛。
但如果業(yè)務需求是這樣的:男生和女生必須使用不同的url進行訪問!
那就只能這么分開編寫成兩條路由了。
注意url中的name屬性,用于后面的反向路由解析。
三、編寫視圖
我們編寫了下面的視圖,很簡單:
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>
很簡單,就是展示學生的信息,沒有需要關注的,僅僅用于表示運行正常,信息顯示正確。
重點是students.html
(多了個s,復數(shù)形式):
!DOCTYPE html>
html lang="en">
head>
meta charset="UTF-8">
title>Title/title>
/head>
body>
h4>歡迎訪問liujiangblog.com, 學習更多Django教程/h4>
{% for student in s %}
{% if student.sex == 'man' %}
p>
姓名:{{ student.name }} nbsp;nbsp;nbsp;nbsp;
詳情:a href="{% url 'man' student.id %}" rel="external nofollow" >{% url 'man' student.id %}/a>
/p>
{% else %}
p>
姓名:{{ student.name }} nbsp;nbsp;nbsp;nbsp;
詳情:a href="{% url 'woman' student.id %}" rel="external nofollow" >{% url 'woman' student.id %}/a>
/p>
{% endif %}
{% endfor %}
/body>
/html>
通過if標簽的判斷,決定最終生成的url是哪種。這里使用了Django內(nèi)置的url模板標簽語法。
訪問students/
頁面顯示結(jié)果:
點擊任何一條學生鏈接都可以正常跳轉(zhuǎn)到詳情頁面。
五、使用get_absolute_url方法
上面的代碼實現(xiàn)了業(yè)務需求,男生和女生自動生成了不一樣的url,而不是我們慣例的/student/
,整個過程也很簡單,比較好理解。
但是,這里有個不足之處,那就是區(qū)分男女生的邏輯放在了HTML模板文件中,這不是個好的做法,也不優(yōu)雅。
實際上我們可以使用get_absolute_url
方法,在Python代碼中實現(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
方法中,我們導入了reverse,這是Django提供的反向解析功能。
reverse能避免我們對url進行硬編碼,它接收多種類型的參數(shù),可以是一個視圖名,也可以是一個url的name。相關的參數(shù)通過args傳遞,這是一個元組,有順序。
上面的代碼中,通過if/else判斷,根據(jù)性別的不同,解析出男女生對應的url。
然后,在students.html
中,我們就可以修改成下面的樣子:
body>
h4>歡迎訪問liujiangblog.com, 學習更多Django教程/h4>
{% for student in s %}
p>
姓名:{{ student.name }} nbsp;nbsp;nbsp;nbsp;
詳情:a href="{{ student.get_absolute_url }}" rel="external nofollow" >{{ student.get_absolute_url }}/a>
/p>
{% endfor %}
/body>
首先,沒有if/else模板標簽了。其次使用{{ student.get_absolute_url }}
來代替url模板標簽。
student是Student模型類的一個實例,它可以訪問類中定義的get_absolute_url方法,從而進入if/else判斷,然后根據(jù)性別的不同,reverse出不同的url字符串,并在HTML模板中展示出來。
整個HTML模板顯得更加簡潔優(yōu)雅,最后的頁面結(jié)果也是完全一樣的。實際上,這里也體現(xiàn)出了Django的模型層和模板層的高度配合。
六、總結(jié)思考
例子很簡單,無非就是在Student模型中添加了一個get_absolute_url
方法。但是如果仔細思考一下我們會發(fā)現(xiàn)這里面有很多體現(xiàn)語言特點的東西:
Django本身沒有實現(xiàn)一個基本的get_absolute_url
方法,在models.Model
中也沒有get_absolute_url
方法的影子,所以這個方法其實只是個思路,沒有實質(zhì)。
get_absolute_url
方法本質(zhì)上只是一個類的實例方法,既然Django內(nèi)部的代碼沒有實現(xiàn)它,那么實際上我們可以給它任意命名,比如改成get_url
。你可以試試,它絕對能正常工作。但要小心的是,Django核心源碼雖然沒有定義get_absolute_url
方法,在admin后臺和feed框架等地方卻可能使用了這個get_absolute_url
方法,所以在非必須時,不要修改這個方法名。
繼續(xù)拓展思維,既然可以自定義get_absolute_url
方法,那我可不可以在模型中添加任何我需要的實例方法呢?當然可以!并且這是最強大最靈活的方式!比如根據(jù)用戶的不同,為模型添加一個user_control
方法,提供不同的信息,控制訪問權限,切換頁面主題等等。
到此這篇關于Django的get_absolute_url方法的使用的文章就介紹到這了,更多相關Django get_absolute_url方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Django靜態(tài)資源URL STATIC_ROOT的配置方法
- Django URL傳遞參數(shù)的方法總結(jié)
- Django中URL的參數(shù)傳遞的實現(xiàn)
- 在Django中URL正則表達式匹配的方法
- Django url,從一個頁面調(diào)到另個頁面的方法
- Django web框架使用url path name詳解
- Django框架教程之正則表達式URL誤區(qū)詳解
- Django中URL視圖函數(shù)的一些高級概念介紹
- 獲取Django項目的全部url方法詳解