美文网首页
搭建博客笔记: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