SharEDITor

从0到1搭建个人网站 六-路由的使用

全栈技术 从0到1搭建个人网站 发表于 2017-07-17 17:15:38 阅读741次


路由是web框架的关键内容,定义了不用的url规则映射到的处理逻辑,本节通过文章的列表页和详情页来说明路由的设置和使用方法

请尊重原创,转载请注明来源网站www.shareditor.com以及原始链接地址

指定标签的文章列表页

上一节完成的首页部分每个标签有对应的一块展示区域,我们希望点击标题可以进入到这个标签的文章列表页。我们来定义如下路由规则,修改shareditor/urls.py,为urlpatterns增加如下一行:

url(r'^bloglistbytag', views.blog_list_by_tag, name='blog_list_by_tag')

这个意思是说对于url路径为bloglistbytag的网页,直接调用views.blog_list_by_tag来执行逻辑。其中的name是用来在模板中利用“url”模板语法使用的,马上会看到

在web/views.py中添加如下函数:

def blog_list_by_tag(request):
    if 'tagname' in request.GET:
        tag_name = request.GET['tagname']
        blog_posts = BlogPost.objects.filter(tags__name=tag_name)
        latest_blog_posts = BlogPost.objects.order_by('create_time')[0:5]
        return render(request, 'web/blog_list_by_tag.html', {'tag_name': tag_name, 'blog_posts': blog_posts,
                                                             'latest_blog_posts': latest_blog_posts})
    else:
        return HttpResponse('404')

这里首先通过获取GET请求的tagname参数来获取到标签名,然后通过model层查询数据库获取导数据,并通过web/templates/web/blog_list_by_tag.html这个模板来渲染的,这个模板如下样子:

{% extends "web/base.html" %}

{% block title %}
    {{ tag_name }}
{% endblock %}

{% block body %}

    <div class="row" style="margin-right: 0">
        <div class="col-sm-3 col-xs-1"></div>
        <div class="col-sm-6 col-xs-10">
            <h1>{{ tag_name }}</h1>
        </div>
        <div class="col-sm-3 col-xs-1"></div>
    </div>

    <div class="row" style="margin-right: 0">
        <div class="col-sm-3 col-xs-1"></div>
        <div class="col-sm-6 col-xs-10">
            {% for blog_post in blog_posts %}
                <h4><a href="">{{ blog_post }}</a>({{ blog_post.create_time|date:'Y-m-d' }})</h4>
            {% endfor %}
        </div>
    </div>

{% endblock %}

以上我们定义了一个标签列表页,打开这个url可以看到效果:http://127.0.0.1:8000/bloglistbytag?tagname=%E4%BB%8E0%E5%88%B01%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E7%BD%91%E7%AB%99

 

但是我们怎么通过首页链接进到这个列表页呢?我们修改web/templates/web/index.html,把其中的

<h3>{{ tag }}({{ tag.blogpost_set.count }})</h3>

改成

<h3><a href="{% url 'blog_list_by_tag' %}?tagname={{ tag }}">{{ tag }}({{ tag.blogpost_set.count }})</a></h3>

这里面我们见识到了url模板语法,他根据指定的路由名来去urls.py中寻找对应的逻辑函数并执行,同时通过url参数来传递变量

 

文章详情页的路由

如上面同样的方法,我们自己设计自己的文章详情页,我自己的详情页模板可以直接参考https://github.com/warmheartli/shareditor/blob/master/web/templates/web/blog_show.html

详情页的逻辑代码如下:

def blog_show(request):
    if 'blogId' in request.GET:
        blog_id = request.GET['blogId']
        blog_post = BlogPost.objects.get(id=blog_id)
        latest_blog_posts = BlogPost.objects.order_by('create_time')[0:5]
        tag_blog_posts = BlogPost.objects.filter(tags__name=blog_post.tags.first())
        tags = Tag.objects.all()
        prev_blog_post = BlogPost.objects.filter(tags__name=blog_post.tags.first()).filter(id__gt=blog_post.id).order_by('id')[0:1]
        next_blog_post = BlogPost.objects.filter(tags__name=blog_post.tags.first()).filter(id__gt=blog_post.id).order_by('id').reverse()[0:1]
        return render(request, 'web/blog_show.html', {'blog_post': blog_post, 'latest_blog_posts': latest_blog_posts,
                                                      'tag_blog_posts': tag_blog_posts, 'tags': tags,
                                                      'prev_blog_post': prev_blog_post, 'next_blog_post': next_blog_post})
    else:
        return HttpResponse('404')

那么,需要添加链接到详情页的地方有很多处,比如首页中改成这样:

 

<p>
    {% for blog_post in tag.blogpost_set.all %}
        <a href="{% url 'blog_show' %}?blogId={{ blog_post.id }}">
            {{ blog_post.title }}
        </a>
    {% endfor %}
</p>

再比如标签列表页改成这样:

<h4><a href="{% url 'blog_show' %}?blogId={{ blog_post.id }}">{{ blog_post }}</a>({{ blog_post.create_time|date:'Y-m-d' }})</h4>

 

小技巧

详情页中我们希望增加“前一篇”和“后一篇”按钮,那么怎么快速获取前一篇和 后一篇呢?如下:

prev_blog_post = BlogPost.objects.filter(tags__name=blog_post.tags.first()).filter(id__lt=blog_post.id).order_by('id').reverse()[0:1]
next_blog_post = BlogPost.objects.filter(tags__name=blog_post.tags.first()).filter(id__gt=blog_post.id).order_by('id')[0:1]

 

总结

这一节主要介绍路由相关内容,其余跟具体网页详细内容需要根据你自己的情况自己定制,如果想参考shareditor可以直接阅读https://github.com/warmheartli/shareditor