美文网首页
搭建博客笔记:py_kouga (四) 详情页面

搭建博客笔记:py_kouga (四) 详情页面

作者: 智勇双全的小六 | 来源:发表于2018-10-17 22:23 被阅读0次

参考教程

  1. Django博客教程
  2. 自强学堂

目前打开详情页面,会报错。所以就来解决一下这个问题。

url 用正则表达式配置

文章详情页的的 url 是一个正则表达式。

from django.conf.urls import url

from . import views

app_name = 'blog'
urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^post/(?P<pk>[0-9]+)/$', views.detail, name='detail'),
]

(?P<name>...) 是正则表达式的分组的命名模式,取此分组中的内容既可以使用索引也可以使用 name

m = re.search(r'^post/(?P<pk>[0-9]+)/$', "post/3/")
if m:
  m.groupdict()
>>> {'pk': '3'}

app_name='blog'

app_name='blog' 告诉 Django 这个 urls.py 模块是属于 blog 应用的,这种技术叫做视图函数命名空间。我们看到 blog\urls.py 目前有两个视图函数,并且通过 name 属性给这些视图函数取了个别名,分别是 index、detail。但是一个复杂的 Django 项目可能不止这些视图函数,例如一些第三方应用中也可能有叫 index、detail 的视图函数,那么怎么把它们区分开来,防止冲突呢?方法就是通过 app_name 来指定命名空间,命名空间具体如何使用将在下面介绍。如果你忘了在 blog\urls.py 中添加这一句,接下来你可能会得到一个 NoMatchReversed 异常。

django reverse 函数

参考文档,https://docs.djangoproject.com/en/2.1/ref/urlresolvers/

blog/models.py

from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
from django.utils.six import python_2_unicode_compatible

@python_2_unicode_compatible
class Post(models.Model):
    ...

    def __str__(self):
        return self.title

    # 自定义 get_absolute_url 方法
    # 记得从 django.urls 中导入 reverse 函数
    def get_absolute_url(self):
        s = reverse('blog:detail', kwargs={'pk': self.pk})
        return s

注意到 URL 配置中的 url(r'^post/(?P<pk>[0-9]+)/$', views.detail, name='detail') ,我们设定的 name='detail' 在这里派上了用场。看到这个 reverse 函数,它的第一个参数的值是 'blog:detail',意思是 blog 应用下的 name=detail 的函数,由于我们在上面通过 app_name = 'blog' 告诉了 Django 这个 URL 模块是属于 blog 应用的,因此 Django 能够顺利地找到 blog 应用下 name 为 detail 的视图函数,于是 reverse 函数会去解析这个视图函数对应的 URL,我们这里 detail 对应的规则就是 post/(?P<pk>[0-9]+)/ 这个正则表达式,而正则表达式部分会被后面传入的参数 pk 替换,所以,如果 Post 的 id(或者 pk,这里 pk 和 id 是等价的) 是 255 的话,那么 get_absolute_url 函数返回的就是 /post/255/ ,这样 Post 自己就生成了自己的 URL。

反复看了几遍,才明白为什么起名叫 reverse 函数。一般而言,都是根据 url 来查找视图函数的。而 reverse 函数又在中间包了一层。在html 中这样配置:

 <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>

Django 的模板解释器肯定会调用 post.get_absolute_url 这个函数,这个函数的输出是 post/1,根据这个路径再去路由里面去查找相应的视图函数。这个过程比起直接在 html 中硬编码,多包了一层函数,使得当 url 地址有变动时,不用去满世界改模板。

总结一下,这个 reverse 函数是写在 models 下面的,reverse 的第一个函数指明了视图函数的位置,其他的可以传点参数。

修改视图模板

主要是把 single.html 改为 detail.html , 把详情页面的链接指向 {{ post.get_absolute_url }}。然后我自己又做了一些视图的继承与拆分。

相关文章

网友评论

      本文标题:搭建博客笔记:py_kouga (四) 详情页面

      本文链接:https://www.haomeiwen.com/subject/hytdzftx.html