django redirect传递参数_Django入门系列(1): 模板中如何避免硬编码URL以及最佳处理方式...

小编前面做了个小调查,发现本公众号超过半数的读者可能还是学生,接触和使用Django还不满6个月,小编决定提笔另启动Django新手入门系列,与现有的Django基础系列并行(实际上现在Django基础系列更新到现在很多新手读起来已经感到有些难度了)。对于中级读者与技术大咖们,小编正在筹备Django源码阅读系列和DRF系列,会提供更深些的内容。本文是Django新手入门小知识系列的第一篇,介绍如何在模板中避免使用硬编码的url以及最佳处理方式。如果你是刚入门Django不久,觉得本文非常有帮助的话,请留个言哈!

88bc0707deea783c543cc49852020dea.png

什么是硬编码(Hard-coded)URL

假如我们有个应用名叫blog,它有一个文章Article模型( 包含title和slug两个字段)。我们还编写了两个视图函数index和detail,一个用于显示文章列表,一个用于显示文章详情(如下所示)。我们的目的是实现当用户访问articles/2/时,用户就可以看到第2篇文章的详情。

#blog/urls.py

from django.urls import path

from . import views

urlpatterns = [
path('', views.index, name='index'),
path('articles//', views.detail, name='detail'),
]

当我们在模板中使用for命令循环遍历文章列表,并给每篇文章添加链接时,我们可以按如下方式操作。在这里你可以看到我们使用了/articles/{{ article.id }}/手动构造了每篇文章对应的url,这没有错,但是一个糟糕的做法。任何通过手动方式拼接而成的url都是硬编码url,是Django建议避免的。试想将来如果你希望改变每篇文章对应的url,比如给每篇文章的url里加入slug字段方便搜索引擎搜索,而你的模板代码中又有多个地方链接了文章对象,那么你将需要改动所有href的属性,而且极有可能会漏掉1个或多个需要传递的参数。

<li><a href="/articles/{{ article.id }}/">{{ article.title }}a>li>

解决方法 - 使用{% url %}标签传递url

Django的推荐做法是使用{% url %}标签传递url,它的意思是访问detail视图函数对应的url,并向其传递article.id作为参数。注意:它可以接收多个参数。

<li><a href="{% url 'detail' article.id %}">{{ article.title }}a>li>

但上述做法还存在一个严重隐患。一个项目里通常包含多个app,假如我们还有一个app名为polls,也有一个detail视图函数,那么Django到底该访问哪个app下detail视图函数对应的url呢?要解决这个问题,我们就需要使用包含有命名空间的urls了, 这才是使用{% url %}标签传递url的正确方式。

第一步: 修改#blog/urls.py, 加入app_name = 'blog'.

#blog/urls.py

from django.urls import path

from . import views

app_name = 'blog'
urlpatterns = [
path('', views.index, name='index'),
path('articles//', views.detail, name='detail'),
]

第二步:给{% url %}标签加入app_name, 这样Django就知道应该访问blog下detail视图函数对应的url了,并传递article.id作为参数。

<li><a href="{% url 'blog:detail' article.id %}">{{article.title}}a>li>

如果现在我们希望每篇文章对应的url还体现slug(比如articles/2/my-first-article-for-seo/,我们可以按如下操作。它的意思是访问blog app下detail视图函数对应的url,并传入article.id和article.slug作为参数。

<li><a href="{% url 'blog:detail' article.id article.slug %}">{{article.title}}a>li>

想想看这么做你会实现目的吗?当然不会。通过{% url %}标签传递参数的个数必须和视图函数对应url地址中参数的数量保持一致。本例中blog:detail对应的url地址里只有article _id这一个参数,而我们却试图向其传递两个参数,自然会出现url解析错误。

path('articles//', views.detail, name='detail'),

为了纠正这个错误,我们只需修改blog/urls.py,给blog:detail对应的url地址新增slug这个参数,如下所示:

path('articles///', views.detail, name='detail'),

放心,现在没有陷阱,也没有错误了。然而使用{% url %}标签传递url的方法一定是完美吗? 答案是否定的。你或许已经发现,我们虽然不用再手动拼接urls, 但每次希望给url传递新的参数时,我们还是需要手动改变模板代码。如果模板里需要改动的链接很多,也是很耗时费力的。

更好的方法 - 使用get_absolute_url方法

假如每篇文章对象都有unique独特的url地址,最好的方法是在模型models.py里通过get_absolute_url方法定义每个对象的绝对url地址,如下所示。这也是小编我推荐的方法。

#blog/models.py

class Article(models.Model):

def get_absolute_url(self):from django.urls import reversereturn reverse('blog:detail', args=[str(self.id), self.slug])

这样我们在模板中按如下使用即可。这样做的好处是,如果有一天你希望改变某篇文章对应的url,你模板里的代码一点都不需要改动,而只需要改变模型里的一句代码即可。

<li><a href="{{ article.get_absolute_url }}">{{ article.title }}a>li>

小结

  • Django项目中应尽量避免手动拼接而形成的硬编码url

  • 使用{% url %}标签传递url时,别忘了使用包含有命名空间的urls

  • 使用{% url %}标签传递的参数个数必须和对应视图函数url可接收的参数数量一致

  • 如果一个对象有独特的url地址,使用get_absolute_url是首选方法

读完本文你的第一感受是什么?

大江狗

2020.4.3

相关阅读

Django基础(28): 如何设计充满陷阱的优美URL

Django常见错误总结: 细数我们一起走过的大坑

Django常见错误信息汇总及解决方案

如果不想错过我们的最新原创文章,关注我们的微信公众号并加星标哦。

3c6a689c2d4f34c081023474ba2a9286.png

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值