Django学习之旅(六)自定义URL规则(博客详情页)

本篇博客同样参照追梦人物老师的博客详情页课程,记录自己的学习过程。本篇博客的重点在于自定义URL规则的使用。

整体结构

-- urls模块中自定义URL --- 从访问路径中获取参数pk

-- 配置视图函数 --- 从urls模块中获取到参数pk,并在视图函数中使用

-- 模型中定义类的get_absolute_url()方法 --- 根据视图函数,并传入参数,解析对应视图函数的url。

-- 在模板html文件中,使用类的get_absolute_url()方法 --- 根据不同的点击,得到不同的url,访问不同的内容。

自定义带参的URL

在blog/urls.py中新增

path('posts/<int:pk>/', views.detail, name='detail')

blog/urls.py文件整体变为

from django.urls import path
from . import views

app_name = 'blog'  # 告诉程序,当前的url模块属于哪个应用,此处是blog应用  ---  试图函数命名空间

urlpatterns = [
    path('', views.index, name='index'),
    path('posts/<int:pk>/', views.detail, name='detail')
]

其中 app_name = 'blog' 告诉程序,当前的url定义属于blog应用;

新增path行第一个参数为新增的相对访问路径:posts/ n/ ,前缀的域名不需要添加。其中<int:pk>表示路径中的 poosts/ 后需要一个int类型的参数pk,任何符合的int类型的数据都可匹配上。

第三项name='detail'表明该视图函数的别名,在Reverse函数中解析URL时会用到。

编写视图函数

def detail(request, pk):
    post = get_object_or_404(Post, pk=pk)  # 系统定义的pk是关键
    return render(request, 'blog/detail.html', context={'post': post})

编写自定义URL对应的视图函数,因为定义的url自带参数,因此在该视图函数中可以使用访问路径中携带的参数pk。

涉及的一个函数: get_object_or_404(Post, pk=pk),表示从数据库中查找满足参数pk=pk的Post类对象,如果不存在则返回404页面错误。

模型中的get_absolute_url方法

为模型添加get_absolute_url方法,便于调用模型进行url解析

from django.urls import reverse  # 域名解析函数    
def get_absolute_url(self):
    # 解析视图函数detail的URL,参数pk其值为self.pk
    return reverse('blog:detail', kwargs={'pk': self.pk})   

 reverse函数:知道视图函数,反转回其url。

其中第一个参数表示视图函数,格式为 "命名空间:别名",别名在定义url中确定。

第二个参数表示视图函数中的参数,不同的视图函数参数,对应不同的url。此处将当前对象本身的pk作为参数传入。因此get_absolute_url函数不需要额外的参数。

在模板中使用带参的url

{% for post in post_list %}
                    ..............
                <article class="post post-{{post.pk}}">

                    
                   <h1 class="entry-title">
                      <a href="{{post.get_absolute_url}}">{{post.title}}</a>
                   </h1>
                        
                   <div class="read-more cl-effect-14">
                      <a href="{{post.get_absolute_url}}" class="more-link">继续阅读</a>
                    </div>

                </article>
                     ..............
{% endfor %}

当点击不同Post对象的 标题 “继续阅读” 时,会调用对应的get_absolute_url()方法。

解析得到对应的detail视图函数的url,从而访问对应的视图函数。

detail视图函数会返回文章的详情页面。

模板中的占位框

如果多个模板只有少部分不同,其余部分的都是相同的。那么可以将不同的部分用占位框表示,将多个模板抽象为一个基目标。

base.html

 ....共用部分....

<main class="col-md-8">
      {% block main %}
      {% endblock main %}
 </main>

 ....共用部分....

 <aside class="col-md-4">
      {% block toc %}
      {% endblock toc %}
 </aside>

 ....共用部分....

其中

{% block main %}
{% endblock main %}

称为占位框,在基模板中预占空间,各子模板继承后进行填充。

{% extends 'base.html' %}

{% block main%}

....子模板内容....

{% endblock main%}

子模版通过{% extends 'base.html' %}基础基模板内容,并在占位框中填充自己的内容。

全部模板内容

templates/base.html

<!DOCTYPE html>
<html>
{% load static %}
<head>
    <title>Black &amp; White</title>

    <!-- meta -->
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- css -->
    <link rel="stylesheet" href="http://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <link rel="stylesheet" href="{% static 'blog/css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'blog/css/pace.css' %}">
    <link rel="stylesheet" href="{% static 'blog/css/custom.css' %}">

    <!-- js -->
    <script src="{%static 'blog/js/jquery-2.1.3.min.js' %}"></script>
    <script src="{% static 'blog/js/bootstrap.min.js' %}"></script>
    <script src="{% static 'blog/js/pace.min.js' %}"></script>
    <script src="{% static 'blog/js/modernizr.custom.js' %}"></script>

</head>

<body>
<div class="container">
    <header id="site-header">
        <div class="row">
            <div class="col-md-4 col-sm-5 col-xs-8">
                <div class="logo">
                    <h1><a href="index.html"><b>Black</b> &amp; White</a></h1>
                </div>
            </div><!-- col-md-4 -->
            <div class="col-md-8 col-sm-7 col-xs-4">
                <nav class="main-nav" role="navigation">
                    <div class="navbar-header">
                        <button type="button" id="trigger-overlay" class="navbar-toggle">
                            <span class="ion-navicon"></span>
                        </button>
                    </div>

                    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                        <ul class="nav navbar-nav navbar-right">
                            <li class="cl-effect-11"><a href="index.html" data-hover="首页">首页</a></li>
                            <li class="cl-effect-11"><a href="full-width.html" data-hover="博客">博客</a></li>
                            <li class="cl-effect-11"><a href="about.html" data-hover="关于">关于</a></li>
                            <li class="cl-effect-11"><a href="contact.html" data-hover="联系">联系</a></li>
                        </ul>
                    </div><!-- /.navbar-collapse -->
                </nav>
                <div id="header-search-box">
                    <a id="search-menu" href="#"><span id="search-icon" class="ion-ios-search-strong"></span></a>
                    <div id="search-form" class="search-form">
                        <form role="search" method="get" id="searchform" action="#">
                            <input type="search" placeholder="搜索" required>
                            <button type="submit"><span class="ion-ios-search-strong"></span></button>
                        </form>
                    </div>
                </div>
            </div><!-- col-md-8 -->
        </div>
    </header>
</div>
<div class="copyrights">Collect from <a href="http://www.cssmoban.com/">网页模板</a></div>
<div class="copyrights">Modified by <a href="http://zmrenwu.com/">追梦人物的博客</a></div>

<div class="content-body">
    <div class="container">
        <div class="row">
            <main class="col-md-8">
                {% block main %}
                {% endblock main %}
            </main>
            <aside class="col-md-4">
                {% block toc %}
                {% endblock toc %}
            </aside>
        </div>
    </div>
</div>
<footer id="site-footer">
    <div class="container">
        <div class="row">
            <div class="col-md-12">
                <p class="copyright">&copy 2017 - 采集自<a href="http://www.cssmoban.com/"
                                                        target="_blank" title="模板之家">模板之家</a>
                    - 由<a href="http://zmrenwu.com/" title="网页模板" target="_blank">追梦人物的博客</a>修改
                </p>
            </div>
        </div>
    </div>
</footer>

<!-- Mobile Menu -->
<div class="overlay overlay-hugeinc">
    <button type="button" class="overlay-close"><span class="ion-ios-close-empty"></span></button>
    <nav>
        <ul>
            <li><a href="index.html">首页</a></li>
            <li><a href="full-width.html">博客</a></li>
            <li><a href="about.html">关于</a></li>
            <li><a href="contact.html">联系</a></li>
        </ul>
    </nav>
</div>

<script src="{% static 'blog/js/script.js' %}"></script>

</body>
</html>

templates/blog/detail.html

{% extends 'base.html' %}

{% block main%}
                <article class="post post-{{post.pk}}">
                    <header class="entry-header">
                        <h1 class="entry-title">{{post.title}}</h1>
                        <div class="entry-meta">
                            <span class="post-category"><a href="#">{{post.category.name}}</a></span>
                            <span class="post-date"><a href="#"><time class="entry-date"
                                                                      datetime="{{post.created_time}}">{{post.created_time}}</time></a></span>
                            <span class="post-author"><a href="#">{{post.author}}</a></span>
                            <span class="comments-link"><a href="#">4 评论</a></span>
                            <span class="views-count"><a href="#">588 阅读</a></span>
                        </div>
                    </header>
                    <div class="entry-content clearfix">
                        {{post.body}}
                    </div>
                </article>
                <section class="comment-area" id="comment-area">
                    <hr>
                    <h3>发表评论</h3>
                    <form action="#" method="post" class="comment-form">
                        <div class="row">
                            <div class="col-md-4">
                                <label for="id_name">名字:</label>
                                <input type="text" id="id_name" name="name" required>
                            </div>
                            <div class="col-md-4">
                                <label for="id_email">邮箱:</label>
                                <input type="email" id="id_email" name="email" required>
                            </div>
                            <div class="col-md-4">
                                <label for="id_url">网址:</label>
                                <input type="text" id="id_url" name="url">
                            </div>
                            <div class="col-md-12">
                                <label for="id_comment">评论:</label>
                                <textarea name="comment" id="id_comment" required></textarea>
                                <button type="submit" class="comment-btn">发表</button>
                            </div>
                        </div>    <!-- row -->
                    </form>
                    <div class="comment-list-panel">
                        <h3>评论列表,共 <span>4</span> 条评论</h3>
                        <ul class="comment-list list-unstyled">
                            <li class="comment-item">
                                <span class="nickname">追梦人物</span>
                                <time class="submit-date" datetime="2012-11-09T23:15:57+00:00">2017年3月12日 14:56</time>
                                <div class="text">
                                    文章观点又有道理又符合人性,这才是真正为了表达观点而写,不是为了迎合某某知名人士粉丝而写。我觉得如果琼瑶是前妻,生了三孩子后被一不知名的女人挖了墙角,我不信谁会说那个女人是追求真爱,说同情琼瑶骂小三的女人都是弱者。
                                </div>
                            </li>
                            <li class="comment-item">
                                <span class="nickname">zmrenwu</span>
                                <time class="submit-date" datetime="2012-11-09T23:15:57+00:00">2017年3月11日 23:56</time>
                                <div class="text">
                                    本能有可能会冲破格局,但格局有时候也会拘住本能。
                                </div>
                            </li>
                            <li class="comment-item">
                                <span class="nickname">蝙蝠侠</span>
                                <time class="submit-date" datetime="2012-11-09T23:15:57+00:00">2017年3月9日 8:56</time>
                                <div class="text">
                                    其实真理一般是属于沉默的大多数的。那些偏激的观点只能吸引那些同样偏激的人。前几年琼瑶告于妈抄袭,大家都表示大快人心,说明吃瓜观众都只是就事论事,并不是对琼瑶有偏见。
                                </div>
                            </li>
                            <li class="comment-item">
                                <span class="nickname">长江七号</span>
                                <time class="submit-date" datetime="2012-11-09T23:15:57+00:00">2017年2月12日 12:56</time>
                                <div class="text">
                                    观点我很喜欢!就是哎嘛本来一清二楚的,来个小三小四乱七八糟一团乱麻夹缠不清,简直麻烦要死
                                </div>
                            </li>
                        </ul>
                    </div>
                </section>
{% endblock main %}


{% block toc %}
                <div class="widget widget-content">
                    <h3 class="widget-title">文章目录</h3>
                    <ul>
                        <li>
                            <a href="#">教程特点</a>
                        </li>
                        <li>
                            <a href="#">谁适合这个教程</a>
                        </li>
                        <li>
                            <a href="#">在线预览</a>
                        </li>
                        <li>
                            <a href="#">资源列表</a>
                        </li>
                        <li>
                            <a href="#">获取帮助</a>
                        </li>
                    </ul>
                </div>
                <div class="widget widget-recent-posts">
                    <h3 class="widget-title">最新文章</h3>
                    <ul>
                        <li>
                            <a href="#">Django 博客开发入门教程:前言</a>
                        </li>
                        <li>
                            <a href="#">Django 博客使用 Markdown 自动生成文章目录</a>
                        </li>
                        <li>
                            <a href="#">部署 Django 博客</a>
                        </li>
                    </ul>
                </div>
                <div class="widget widget-archives">
                    <h3 class="widget-title">归档</h3>
                    <ul>
                        <li>
                            <a href="#">2017 年 5 月</a>
                        </li>
                        <li>
                            <a href="#">2017 年 4 月</a>
                        </li>
                        <li>
                            <a href="#">2017 年 3 月</a>
                        </li>
                    </ul>
                </div>

                <div class="widget widget-category">
                    <h3 class="widget-title">分类</h3>
                    <ul>
                        <li>
                            <a href="#">Django 博客教程 <span class="post-count">(13)</span></a>
                        </li>
                        <li>
                            <a href="#">Python 教程 <span class="post-count">(11)</span></a>
                        </li>
                        <li>
                            <a href="#">Django 用户认证 <span class="post-count">(8)</span></a>
                        </li>
                    </ul>
                </div>

                <div class="widget widget-tag-cloud">
                    <h3 class="widget-title">标签云</h3>
                    <ul>
                        <li>
                            <a href="#">Django</a>
                        </li>
                        <li>
                            <a href="#">Python</a>
                        </li>
                        <li>
                            <a href="#">Java</a>
                        </li>
                        <li>
                            <a href="#">笔记</a>
                        </li>
                        <li>
                            <a href="#">文档</a>
                        </li>
                        <li>
                            <a href="#">AngularJS</a>
                        </li>
                        <li>
                            <a href="#">CSS</a>
                        </li>
                        <li>
                            <a href="#">JavaScript</a>
                        </li>
                        <li>
                            <a href="#">Snippet</a>
                        </li>
                        <li>
                            <a href="#">jQuery</a>
                        </li>
                    </ul>
                </div>
                <div class="rss">
                    <a href=""><span class="ion-social-rss-outline"></span> RSS 订阅</a>
                </div>
{% endblock toc %}

templates/blog/index.html

{% extends 'base.html' %}

{% block main%}
{% for post in post_list %}
                <article class="post post-{{post.pk}}">
                    <header class="entry-header">
                        <h1 class="entry-title">
                            <a href="{{post.get_absolute_url}}">{{post.title}}</a>
                        </h1>
                        <div class="entry-meta">
                            <span class="post-category"><a href="#">{{post.category.name}}</a></span>
                            <span class="post-date"><a href="#"><time class="entry-date"
                                                                      datetime="{{post.created_time}}">{{post.created_time}}</time></a></span>
                            <span class="post-author"><a href="#">{{post.author}}</a></span>
                            <span class="comments-link"><a href="#">4 评论</a></span>
                            <span class="views-count"><a href="#">588 阅读</a></span>
                        </div>
                    </header>
                    <div class="entry-content clearfix">
                        <p>{{post.abstract}}</p>
                        <div class="read-more cl-effect-14">
                            <a href="{{post.get_absolute_url}}" class="more-link">继续阅读 <span class="meta-nav">→</span></a>
                        </div>
                    </div>
                </article>

                {% empty %}
                <div class="no-post">  暂时还没有发布的文章! </div>>
                {% endfor %}
                <!-- 简单分页效果
                <div class="pagination-simple">
                    <a href="#">上一页</a>
                    <span class="current">第 6 页 / 共 11 页</span>
                    <a href="#">下一页</a>
                </div>
                -->
                <div class="pagination">
                    <ul>
                        <li><a href="">1</a></li>
                        <li><a href="">...</a></li>
                        <li><a href="">4</a></li>
                        <li><a href="">5</a></li>
                        <li class="current"><a href="">6</a></li>
                        <li><a href="">7</a></li>
                        <li><a href="">8</a></li>
                        <li><a href="">...</a></li>
                        <li><a href="">11</a></li>
                    </ul>
                </div>
{% endblock main%}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值