django中URL反向解析總結(url/reverse/get_absolute_url)

前言介紹

Django中進行URL反向解析一般有以下三種方式

  • 在模板中使用 {% url 'blog:detail' post.id %}的方法
  • 在view視圖中一般使用reverse() 函數
  • 還有一種特殊情況下使用 get_absolute_url的方法

上面三種方式都可以幫助替代硬編碼簡化程序維護成本

模板中使用url 標籤

用法很簡單,同時也是支持多個參數,比如博客中常用到的

# 無參數,訪問博客首頁
{% url 'blog:index' %}

# 一個參數,訪問指定ID的博客詳情頁
{% url 'blog:detail' post.id %}

上面中的blog:index格式中

  • blog 是在APP下的url.py中定義的app_name ,一般配合項目urls.py 路徑中的namespace 使用
# project/urls.py
urlpatterns = [
    ... ...,
    path('blog/', include('blog.urls', namespace='blog')),
]

# blog/urls.py
app_name = 'blog'
urlpatterns = [
    ... ...,
    path('', views.index, name='index'),
    path('post/<int:id>/', views.detail, name='detail'),
]

  • detail 是具體URL path的別名

比如上述代碼中的 name='index'name='detail',這樣做的好處就是如果URL path 路徑發生了變化,那麼也不用去template模板中修改對應的URL地址,因爲name 沒有變

view視圖中使用reverse函數

reverse的目的和template使用url標籤是一樣的,只是用的位置不一樣而已(url標籤在template模板,而reverse在view 視圖代碼中)

  • 使用URL 別名
>>> from django.urls import reverse
>>> reverse('blog:home')
'/blog/'
>>> reverse('blog:archive')
'/blog/archive/'
  • 使用view函數名

官網教程提示可以使用 view視圖函數名 (reverse(views.home))來解析,但是實際測試是報錯 django.urls.exceptions.NoReverseMatch: Reverse for 'blog.views.home' not found. 'blog.views.home' is not a valid view function or pattern name.

  • 如果帶參數的話,可以使用 args 和 kwargs
>>> from django.urls import resolve
>>> reverse('blog:detail', args=(2, ))
'/blog/post/2/'
>>> reverse('blog:detail', kwargs={'id': 2})
'/blog/post/2/'

參考https://docs.djangoproject.com/en/4.1/ref/urlresolvers/#django.urls.reverse

get_absolute_url定義和使用

先說get_absolute_url的定義,是在對應的Model下,比如Post文章Model

class Post(models.Model):
    ... ...
    def get_absolute_url(self):
        from django.urls import reverse
        return reverse('blog:detail', args=(self.id, ))

其實這裏也看到它其實借用了 reverse來實現,那麼問什麼要單獨定義這麼個函數呢?

原因在於

1、在VIew視圖中如果使用redirect進行跳轉的話,使用直接使用對象,方便很多

from django.shortctus import redirect

def comment(request, post_id):
    post = Post.objects.get(id=post_id)
    # comment 邏輯,評論成功則返回到對應的文章詳情頁
    return redirect(post)

2、在template模板中可以使用 {{ post.get_absolute_url }} 來代替 {% url 'blog:detail' post.id %}

3、擴展: 後續如果學習了 django restframework 之後,在使用viewset的時候,詳情頁的返回也是默認調用 get_absolute_url

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章