登录        注册
本站基于Django开发,源码 Github 欢迎 Fork、Star。由于站点升级导致评论区留言信息丢失,欢迎前来发表新的评论

Django个人博客开发十 | 博客首页开发二

Django stormsha 9141浏览 219喜欢 1评论
本渣渣不专注技术,只专注使用技术,不是一个资深的coder,是一个不折不扣的copier

本节,写的代码量有点大,不要慌,主要是理解,渲染数据的逻辑,不要纠结于局部。

【提示】——重点领悟 用户请求、路由、视图、自定义模板标签的关系,只要理解了这几个过程的逻辑和联系,前端写再多的代码,都不会感觉到慌乱

1、理论讲堂

视图函数(类),简称视图,是一个简单的 Python 函数(类),它接收 Web 请求并且返回 Web 响应。响应可以是一个网页的 HTML 内容,一个重定向,一个404错误,一个 XML 文档,或者一张图片,甚至一个文件。无论视图本身包含什么逻辑,都要返回响应。代码书写位置无要求,只要它在你当前项目目录下面。除此之外没有更多的要求——可以说 "没有什么神奇的地方"。为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中

正确的流程,应该是,先分析前端代码,来配置路由,然后书写视图逻辑

因为 Django 工作原理是:

用户发出 http 请求 -> 匹配路由 -> 进入视图 -> 根据用户请求在视图内编写逻辑 -> 把渲染后的 html 代码返给浏览器 -> 浏览器解析后呈现给用户

用户请求:就是 url(网址)

路由:Django 根据 用户请求的地址,来判断用户是干啥的,把任务交给指定的视图函数去干活

视图:接收到路由委派的任务后,开始操作数据库,增、删、查,基本就这些个活,干好后,把渲染后的thml交给浏览器,浏览器解析后展示给用户要看的东东

下面自上而下,自左而右,分块来渲染数据,只捡重要的几块分区,在结构整理中的四个大区为主,没有提到的数据渲染,可以仿照其它功能实现,下边不解释,直接贴代码,重点通过代码看渲染数据的方法和逻辑

推荐学习:django 的模板语言template ,自定义过滤器,自定义标签,模板继承

2、导航栏

blog ->templates -> base.html

头部引入文件,staticfiles静态文件、blog_tags 自定义模板标签,记得无论那个页面只要用到里边的函数都要在头部引入

{% load staticfiles %}
{% load blog_tags %}
<!DOCTYPE HTML>
<html>

导航栏渲染数据

<!--导航条-->
<div id="nav-header" class="navbar">
    <ul class="nav">
        <!--获取一级分类信息-->
        {% get_bigcategory_list as bigcategory %}
        <li id="menu-item-44"
            class="menu-item menu-item-type-custom menu-item-object-custom {% if not category %}current-menu-item current_page_item{% endif %} menu-item-home menu-item-44"><a
                href="/">首页</a></li>

        <!--导航条一级分类渲染-->
        {% for big in bigcategory %}

            <!--获取二级分类信息-->
            {% get_category_list big.id as cate %}

            <!--如果一级分类下有二级分类则进行渲染-->
            {% if cate %}
                <li id="menu-item-14"
                        class="menu-item menu-item-type-taxonomy menu-item-object-category {% if category == big.slug %}current-menu-item {% endif %} menu-item-has-children menu-item-14">
                        <a href="{% url 'blog:category' big.slug '' %}">{{ big.name }}</a>
                            <ul class="sub-menu">
                                <!--导航条二级分类渲染-->
                                {% for c in cate %}
                                        <li id="menu-item-19" class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-19"><a href="{% url 'blog:category'  big.slug   c.slug  %}">{{ c.name }}</a></li>
                                {% endfor %}
                            </ul>
                </li>

            <!--无二级分类的一级分类渲染-->
            {% else %}
                <li id="menu-item-851" class="menu-item menu-item-type-post_type menu-item-object-page {% if category == big.slug %}current-menu-item {% endif %} menu-item-851"><a href="{% url 'blog:category' big.slug '' %}">{{ big.name }}</a></li>
            {% endif %}
        {% endfor %}
        <!--导航条结束-->

        <!--搜索框-->
        <!--目前搜索框功能感觉没必要没做-->
        <li style="float:right;">
            <div class="toggle-search"><i class="fa fa-search"></i></div>
            <div class="search-expand" style="display: none;">
                <div class="search-expand-inner">
                    <form method="get" class="searchform themeform"
                          onsubmit="location.href='/?s=' + encodeURIComponent(this.s.value).replace(/%20/g, '+'); return false;"
                          action="/">
                        <div><input type="ext" class="search" name="s" onblur="if(this.value=='')this.value='search...';"
                                    onfocus="if(this.value=='search...')this.value='';" value="search..."></div>
                    </form>
                </div>
            </div>
        </li>
        <!--搜索框结束-->

    </ul>
</div>
<!--导航条结束-->

blog -> templatetags -> blog_tags.py

# 创建了新的tags标签文件后必须重启服务器

from django import template
from ..models import Article, Category, Tag, Carousel, FriendLink, BigCategory, Activate, Keyword
from django.db.models.aggregates import Count
from django.utils.html import mark_safe
import re

# 注册自定义标签函数
register = template.Library()


# 获取导航条大分类查询集
@register.simple_tag
def get_bigcategory_list():
    """返回大分类列表"""
    return BigCategory.objects.all()


# 返回文章分类查询集
@register.simple_tag
def get_category_list(id):
    """返回小分类列表"""
    return Category.objects.filter(bigcategory_id=id)

Templatetags:

必须写的头部

from django import template
# 注册自定义标签函数
register = template.Library()

个人理解:自定义模版标签,和(view)视图的区别就是不需要接收 request 请求,只需要在模板也即前端页面接收参数,返回需要的数据进行展示即可。也就意味着,除了需要和用户交互的内容,比如用户给某篇章点赞,需要使用 Jquery + ajax 实现无刷新给页面喜欢数量加一,这个就需要 Jquery 接收到用户点击行为后,AJAX 携带信息给指定路由发出请求,视图接收到请求,把处理结果返给 AJAX 实现无数刷新地更新喜欢量。只要不涉及交互,的数据请求都可以放在 Templatetags 处理前端需要展示的数据

更多自定义过滤函数装饰器:官方文档

3、幻灯片

blog ->templates -> index.html

<div id="wowslider-container1">
    <div class="ws_images">

        <ul>
            {% get_carousel_index as carousels %}
            {% for carousel in carousels %}

            <li>
                <a target="_blank" href="{{ carousel.url }}" title="{{ carousel.content }}">
                    <img src="{{ carousel.img_url }}" title="{{ carousel.title }}" alt="{{ carousel.title }}"/>
                </a>
            </li>
            {% endfor %}
        </ul>
    </div>

    <div class="ws_thumbs">
        <div>
            {% get_carousel_index as carousels %}
            {% for carousel in carousels %}
            <a target="_blank" href="#" title="{{ carousel.title }}"><img src="{{ carousel.img_url }}"/></a>
            {% endfor %}
        </div>
    </div>
    <div class="ws_shadow"></div>
</div>

blog -> templatetags -> blog_tags.py

# 获取滚动的大幻灯片查询集、获取左侧的幻灯片查询集,这两个部分用的图片是一样的
@register.simple_tag
def get_carousel_index():
    return Carousel.objects.filter(number__lte=5)

在数据库内给幻灯片添加一些图片

20331

运行项目,观看效果

20332

4、热门文章

blog ->templates -> index.html

<div class="hot-posts">
    <h2 class="title">热门排行</h2>
    <ul>
    {% get_article_list 'views' 5 as hot_article %}
        {% for hot in hot_article %}
        <li><p><span class="muted"><a href="javascript:;" data-action="ding" data-id="{{ hot.id }}" id="Addlike" class="action"><i
                class="fa fa-heart-o"></i><span class="count">{{ hot.loves }}</span> 喜欢</a></span></p><span class="label label-1">{{ forloop.counter}}</span><a
                href="/article/{{ hot.slug }}" title="{{ hot.title }}">{{ hot.title }}</a></li>
        {% endfor %}
    </ul>
</div>

blog -> templatetags -> blog_tags.py

# 获取热门排行数据查询集,参数:sort 文章类型, num 数量
@register.simple_tag
def get_article_list(sort=None, num=None):
    """获取指定排序方式和指定数量的文章"""
    if sort:
        if num:
            return Article.objects.order_by(sort)[:num]
        return Article.objects.order_by(sort)
    if num:
        return Article.objects.all()[:num]
    return Article.objects.all()

5、文章列表

blog ->templates -> index.html

{% for article in page_obj %}
    <article class="excerpt">
        <header><a class="label label-important" href="/category/{{ article.category.bigcategory.name }}/{{ article.category.name|lower }}">{{ article.category.name }}<i class="label-arrow"></i></a>
            <h2><a target="_blank" href="/article/{{ article.slug }}" title="{{ article.title }}">{{ article.title }} </a></h2>
        </header>
        <div class="focus"><a target="_blank" href="/article/{{ article.slug }}"><img class="thumb" width="200" height="123" src="{{ article.img_link }}"
                                                                                           alt="{{ article.title }}"/></a></div>
        <span class="note">{{ article.summary }}</span>
        <p class="auth-span">
            <span class="muted"><i class="fa fa-user"></i> <a href="/author/{{ article.author }}">{{ article.author }}</a></span>
            <span class="muted"><i class="fa fa-clock-o"></i> {{ article.create_date|date:'Y-m-d' }}</span> <span class="muted"><i class="fa fa-eye"></i> {{ article.views }}浏览</span>
            <span class="muted">
                <i class="fa fa-comments-o"></i> 
                    <a target="_blank" href="/article/{{ article.slug }}#comments">评论</a>
            </span>
            <span class="muted">
                <a href="javascript:;" data-action="ding" data-id="{{ article.id }}" id="Addlike" class="action">
                <i class="fa fa-heart-o"></i>
                <span class="count">{{ article.loves }}</span>喜欢</a>
            </span>
        </p>
    </article>
{% empty %}
    <div class="no-post">暂时还没有发布的文章!</div>
{% endfor %}

这里没用到自定义模板标签

20333

6、侧边栏

blog ->templates -> base_right.html

首先个人联系方式的矢量图没显示出来,需要引入一下矢量图文件

20334

首先去awesome官网下载 font-awesome-4.7.0或者拷贝Github项目中的矢量文件,然后把文件放入 static 静态文件中,然后在

blog ->templates -> base.html中的head标签引入头部文件的地方导入路径

<link rel='stylesheet' id='page-list-style-css'  href='/static/font-awesome-4.7.0/css/font-awesome.min.css' type='text/css' media='all' />

20335

侧边栏热门专题轮播图

blog ->templates -> base_right.html

不要忘记在头部引入自定义模板标签

{% load blog_tags %}

热门专题轮播图

<div class="widget widget_metaslider_widget">
    <!--热门专题-->
    <div class="title"><h2>热门专题</h2></div><!-- meta slider -->
    <div style="width: 100%;" class="metaslider metaslider-nivo metaslider-2698 ml-slider meta-slider">
        <div id="metaslider_container_2698">
            <div class='slider-wrapper theme-bar'>
                <div class='ribbon'></div>
                <div id='metaslider_2698' class='nivoSlider'>
                    {% get_carousel_right as carousels %}
                    {% for carousel in carousels  %}
                        <a href="{{ carousel.url }}" target="_blank">
                            <img src="{{ carousel.img_url }}" height="300" width="320" data-title="{{ carousel.content }}"
                                 title="{{ carousel.title }}" alt="{{ carousel.title }}" class="slider-2698 slide-1720"/>
                        </a>
                    {% endfor %}
                </div>
            </div>
        </div>
        <!--热门专题结束-->

        <script type="text/javascript">
            var metaslider_2698 = function ($) {
                $('#metaslider_2698').nivoSlider({
                    boxCols: 7,
                    boxRows: 5,
                    pauseTime: 3000,
                    effect: "random",
                    controlNav: false,
                    directionNav: true,
                    pauseOnHover: true,
                    animSpeed: 600,
                    prevText: "&lt;",
                    nextText: "&gt;",
                    slices: 15,
                    manualAdvance: false
                });
            };
            var timer_metaslider_2698 = function () {
                var slider = !window.jQuery ? window.setTimeout(timer_metaslider_2698, 100) : !jQuery.isReady ? window.setTimeout(timer_metaslider_2698, 1) : metaslider_2698(window.jQuery);
            };
            timer_metaslider_2698();
        </script>
    </div>
    <!--// meta slider-->
</div>

blog -> templatetags -> blog_tags.py

# 获取右侧栏热门专题幻灯片查询集
@register.simple_tag
def get_carousel_right():
    return Carousel.objects.filter(number__gt=5, number__lte=10)

Carousel表前五个是首页大轮播图、后五个是热门专题轮播图

文章归档

blog ->templates -> base_right.html

<div class="widget widget_archive">
    <!--文章归档-->
    <div class="title"><h2>文章归档</h2></div>
        {% get_data_date as data_date %}
        <ul>
            {% if data_date %}
                {% for date in data_date %}
                    <li><a href='{% url 'blog:date' date|date:'Y' date|date:'m' %}'>{{ date|date:'Y-m' }}</a></li>
                {% endfor %}
            {% else %}
                <div>近期没有发表过文章</div>
            {% endif %}
        </ul>
</div>
<!--文章归档结束-->

blog -> templatetags -> blog_tags.py

# 获取归档文章查询集
@register.simple_tag
def get_data_date():
    """获取文章发表的不同月份"""
    article_dates = Article.objects.datetimes('create_date', 'month', order='DESC')
    return article_dates

猜你喜欢

blog ->templates -> base_right.html

<!--猜你喜欢-->
<div class="widget d_postlist">
    <div class="title"><h2>猜你喜欢</h2></div>
    <ul>
        {% get_article_list 'loves' 6 as hot_tag %}
        {% for hot in hot_tag %}
        <li>
            <a href="/article/{{ hot.slug }} " title="{{ hot.title }}"><span class="thumbnail"><img
                src="{{ hot.img_link }}" alt="{{ hot.title }}"/></span>
                <span class="text">{{ hot.title }}</span>
                <span class="muted">{{ hot.create_date|date:'Y-m-d' }}</span>
                <span class="muted">{{ hot.loves }}喜欢</span>
            </a>
        </li>
        {% endfor %}
    </ul>
</div>
<!--猜你喜欢结束-->

blog -> templatetags -> blog_tags.py

# 文章相关标签函数,和热门文章使用同一个函数
@register.simple_tag
def get_article_list(sort=None, num=None):
    '''获取指定排序方式和指定数量的文章'''
    if sort:
        if num:
            return Article.objects.order_by(sort)[:num]
        return Article.objects.order_by(sort)
    if num:
        return Article.objects.all()[:num]
    return Article.objects.all()

和热门文章使用同一个函数

标签云和友情链接

blog ->templates -> base_right.html

<!--标签云-->
<div class="widget d_tag">
    <div class="title"><h2>标签云</h2></div>
    <div class="d_tags">
        {% get_tag_list as tags %}
        {% for tag in tags %}
            <!--tag.total_num直接获得标签次标签下的文章数-->
            <a title="{{ tag.total_num }}个话题" href="{% url 'blog:tag' tag.name %}">{{ tag.name }} ({{ tag.total_num }})</a>
        {% endfor %}
    </div>
</div>
<!--标签云结束-->

<!--友情链接-->
<div class="widget widget_links">
    <div class="title"><h2>友情链接</h2></div>
        {% get_friends as friends %}
        <ul class='xoxo blogroll'>
            {% if friends %}
                {% for friend in friends %}
                    <li><a href="{{ friend.link }}" target="_blank">{{ friend.name }}</a></li>
                {% endfor %}
            {% else %}
                <div>&nbsp;&nbsp;暂无友链,欢迎来战</div>
            {% endif %}
        </ul>
</div>
<!--友情链接结束-->

storm -> templatetags -> blog_tags.py

# 获取文章标签信息,参数文章ID
@register.simple_tag
def get_article_tag(article_id):
    return Tag.objects.filter(article=article_id)

【友情提示】——如果发现有表达错误,或者知识点错误,或者搞不懂的地方,请及时留言,可以在评论区互相帮助,让后来者少走弯路是我的初衷。我也是一步步摸着石头走过来的,深知网络上只言片语的图文教程,给初学者带来的深深困扰。

【建议】——在对项目结构不太熟悉时,参照完整源码少走弯路

转载请注明: StormSha » Django个人博客开发十 | 博客首页开发二

发表我的评论

表情
(1)个小伙伴在吐槽|1条评论
  1. 注册用户头像

    我想问一下{%if category == big.slug %}中的category是从哪来的,非常感谢

    Yzaaa 2020年1月6日 21:11 回复