4

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

 3 years ago
source link: http://www.lcsays.com/blogshow?blogId=131
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

全栈技术 从0到1搭建个人网站 发表于 2017-07-17 17:15:38 阅读956次
thumb_497_default_big.jpeg
路由是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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK