bbs项目(部分讲解)

首页

导航条和轮播图

创建index.html,添加路由,get请求时返回index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
    <script src="/static/jQuery.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
</head>
<body>
<div class="my_nav">
    <nav class="navbar navbar-inverse">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                        data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="#">博客园</a>
            </div>

            <!-- Collect the nav links, forms, and other content for toggling -->
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class="nav navbar-nav">
                    <li class="active"><a href="#">首页 <span class="sr-only">(current)</span></a></li>
                    <li><a href="#">新闻</a></li>
                </ul>
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="#">jasper</a></li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                           aria-expanded="false">更多 <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#">修改密码</a></li>
                            <li><a href="#">后台管理</a></li>
                            <li><a href="#">修改头像</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="#">退出</a></li>
                        </ul>
                    </li>
                </ul>
            </div><!-- /.navbar-collapse -->
        </div><!-- /.container-fluid -->
    </nav>
</div>
<div class="container-fluid">
    <div class="row">
        <div class="view_left">
            <div class="col-md-2">
                <div class="list-group">
                    <a href="#" class="list-group-item active">
                        头条
                    </a>
                    <a href="#" class="list-group-item">286 亿元!败了的 Google 是否会为 Android 交最贵罚单?</a>
                    <a href="#" class="list-group-item">苹果灵动岛华而不实?网友整活改进,竟可以“一键抢大米”</a>
                    <a href="#" class="list-group-item">“AI 终有可能消灭人类!”</a>
                    <a href="#" class="list-group-item">Python 3.14 将比 C++ 更快</a>
                </div>
                <div class="list-group">
                    <a href="#" class="list-group-item active">
                        热点
                    </a>
                    <a href="#" class="list-group-item">《羊了个羊》否认抄袭;安卓反垄断案再次败诉,罚款金额下降至286亿元</a>
                    <a href="#" class="list-group-item">聊聊Redis的数据热点问题</a>
                    <a href="#" class="list-group-item">抖音开放平台,究竟开放了什么?</a>
                    <a href="#" class="list-group-item">谷歌CEO皮查伊暗示要裁员;华为研发投入位居首位;Android 13首个安全更新|极客头条</a>
                </div>
            </div>
        </div>
        <div class="view_mid">
            <div class="col-md-7">
                <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
                    <!-- Indicators -->
                    <ol class="carousel-indicators">
                        <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
                        <li data-target="#carousel-example-generic" data-slide-to="1"></li>
                        <li data-target="#carousel-example-generic" data-slide-to="2"></li>
                    </ol>

                    <!-- Wrapper for slides -->
                    <div class="carousel-inner" role="listbox">
                        <div class="item active">
                            <img src="../media/slideshow/1.png" alt="...">
                            <div class="carousel-caption">
                                ...
                            </div>
                        </div>
                        <div class="item">
                            <img src="../media/slideshow/2.png" alt="...">
                            <div class="carousel-caption">
                                ...
                            </div>
                        </div>
                        <div class="item">
                            <img src="../media/slideshow/3.png" alt="...">
                            <div class="carousel-caption">
                                ...
                            </div>
                        </div>
                    </div>

                    <!-- Controls -->
                    <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
                        <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
                        <span class="sr-only">Previous</span>
                    </a>
                    <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
                        <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
                        <span class="sr-only">Next</span>
                    </a>
                </div>
            </div>
        </div>
        <div class="view_right">
            <div class="col-md-3">
                <div class="panel panel-primary">
                    <div class="panel-heading">
                        <h3 class="panel-title">广告招租</h3>
                    </div>
                    <div class="panel-body">
                        vx:xxx
                    </div>
                </div>
                <div class="panel panel-danger">
                    <div class="panel-heading">
                        <h3 class="panel-title">广告招租</h3>
                    </div>
                    <div class="panel-body">
                        vx:xxx
                    </div>
                </div>
                <div class="panel panel-info">
                    <div class="panel-heading">
                        <h3 class="panel-title">广告招租</h3>
                    </div>
                    <div class="panel-body">
                        vx:xxx
                    </div>
                </div>
                <div class="panel panel-success">
                    <div class="panel-heading">
                        <h3 class="panel-title">广告招租</h3>
                    </div>
                    <div class="panel-body">
                        vx:xxx
                    </div>
                </div>
                <div class="panel panel-warning">
                    <div class="panel-heading">
                        <h3 class="panel-title">广告招租</h3>
                    </div>
                    <div class="panel-body">
                        vx:xxx
                    </div>
                </div>

            </div>
        </div>
    </div>
</div>
</body>
</html>

首页文章列表

登陆超级管理员录入数据

先在admin.py中将表注册后 可以看到表名

from django.contrib import admin
from .models import *

# Register your models here.
admin.site.register(UserInfo)
admin.site.register(Blog)
admin.site.register(Tag)
admin.site.register(Classify)
admin.site.register(Article)
admin.site.register(UpAndDown)
admin.site.register(Comment)

注意:显示表名需在models.py中创建表时添加一个Meta

class Meta:
    verbose_name_plural = '个人站点表'

定义字段时添加属性verbose_name在添加数据时显示
在创建表时定义双下str方法可以自定义显示的创建对象名字

def __str__(self):
    return self.title

开启media访问

Django中的media文件夹一般用来存放文件,图片等不重要的数据,想在前端通过路径访问media中的数据,是不可以的,需要开启media访问

settings.py中添加

MEDIA_ROOT = os.path.join(BASEDIR, 'media')

urls中添加

from django.views.static import serve
from django.conf import settings

path('media/<path:path>', serve, {'document_root':settings.MEDIA_ROOT})

注意:static文件夹已经默认开启,可以从浏览器进行访问,所以staticmedia文件夹下不能放重要文件

图片防盗链

有的网站有上传图片功能,可以上传到该网站,然后再自己的网站使用,这样就不会消耗自己的带宽

图片防盗链就是抑制这种行为,本质原理是:浏览器发送http请求,请求头中会携带referer参数,是一个url地址,表示上一次访问的地址,图片防盗链可以跟据这个地址判断是不是自己的网址发的请求,如果不是直接拒绝响应。

首页文章渲染

views.py
后端返回所有文章

def index(request):
    article_query_set = Article.objects.all()
    return render(request, 'index.html', context={'article_query_set': article_query_set})

index.html

<div class="article" style="margin-top: 20px">
    {% for foo in article_query_set %}
        <div style="margin-top: 20px">
            <h4 class="media-heading"><a href="">{{ foo.title }}</a></h4>
            <hr>
            <div class="media">
                <div class="media-left">
                    <a href="#">
                        <img class="media-object" src="/media/{{ foo.blog.userinfo.icon }}" alt="..."
                             width="60px" height="60px">
                    </a>
                </div>
                <div class="media-body">
                    <h4 class="media-heading">{{ foo.desc }}</h4>
                </div>
            </div>

            <div class="" style="margin-top: 20px">
                <a href="{{ foo.blog.userinfo.username }}"><span
                        style="padding: 10px;font-size: 13px">{{ foo.blog.userinfo.username }}</span></a>
                <span style="padding: 5px;font-size: 13px">{{ foo.create_time|date:'Y-m-d H:s' }}</span>
                <span style="padding: 5px;font-size: 13px"><i class="fa fa-thumbs-o-up"
                                                              aria-hidden="true"></i>{{ foo.up_num }}</span>
                <span style="padding: 10px;font-size: 13px"><i class="fa fa-thumbs-o-down"
                                                               aria-hidden="true"></i>{{ foo.down_num }}</span>
                <span style="padding: 10px;font-size: 13px"><i class="fa fa-commenting"
                                                               aria-hidden="true"></i>{{ foo.comment_num }}</span>
            </div>
        </div>

    {% endfor %}

</div>

个人站点页面搭建

路由配置

当点击用户名 则跳转到用户对应的站点(如果存在)不存在就返回404界面

# 站点匹配 必须放最后
path('<str:name>/', views.site),

后端

def site(request, name, **kwargs):
    user = UserInfo.objects.filter(username=name).first()
    if not user:
        return render(request, 'error.html')
    article_set = user.blog.article_set.all()
    return render(request, 'site.html', locals())

404界面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>404</title>
</head>
<body>
<script type="text/javascript"
        src="//qzonestyle.gtimg.cn/qzone/hybrid/app/404/search_children.js"
        charset="utf-8">
</script>
</body>
</html>

个人站点前端

使用模板的继承,变得只是中间文章的展示,分类标签随笔部分不变。
base.html

<head>
    <meta charset="UTF-8">
    <title>
        {% block title %}

        {% endblock %}
    </title>
    <script src="/static/jQuery.js"></script>
    <link rel="stylesheet" href="/static/bootstrap-3.4.1-dist/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/static/font-awesome-4.7.0/css/font-awesome.min.css">
    {% block link %}

    {% endblock %}
</head>
<body>
<div class="main">
    <div class="header">
        {% block handle %}

        {% endblock %}
    </div>

    <div class="container-fluid">
        <div class="row">
            <div class="col-md-2">
                <div class="list-group">
                    <a href="#" class="list-group-item active">
                        我的标签
                    </a>
                    {% for foo in tag_res %}
                        <div class="list-group">
                        <a href="/{{ user.username }}/tag/{{ foo.0 }}.html"
                           class="list-group-item"><span>{{ foo.1 }}</span>
                            <span>({{ foo.2 }})</span></a>
                    {% endfor %}
                    </div>

                </div>
                <div class="list-group">
                    <a href="#" class="list-group-item active">
                        我的分类
                    </a>
                    {% for foo in classify_res %}
                        <div class="list-group">
                        <a href="/{{ user.username }}/classify/{{ foo.0 }}.html"
                           class="list-group-item"><span>{{ foo.1 }}</span>
                            <span>({{ foo.2 }})</span></a>
                    {% endfor %}
                    </div>
                </div>
                <div class="list-group">
                    <a href="#" class="list-group-item active">
                        随笔分类
                    </a>
                    {% for foo in date_res %}
                        <div class="list-group">
                        <a href="/{{ user.username }}/archive/{{ foo.0|date:'Ym' }}.html"
                           class="list-group-item"><span>{{ foo.0|date:'Y年m月' }}</span>
                            <span>({{ foo.1 }})</span></a>
                    {% endfor %}
                    </div>
                </div>
            </div>
            <div class="col-md-10">
                {% block crticle %}

                {% endblock %}
            </div>
        </div>
    </div>
</div>
</body>

site.html

{% extends 'base.html' %}

{% block title %}
    {{ user.username }}
{% endblock %}

{% block link %}

{% endblock %}

{% block handle %}
    <div class="my_nav">
        <nav class="navbar navbar-inverse">
            <div class="container-fluid">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                            data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="#">{{ user.username }}</a>
                </div>

                <!-- Collect the nav links, forms, and other content for toggling -->
                <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                    <ul class="nav navbar-nav">
                    </ul>
                    <ul class="nav navbar-nav navbar-right">
                        <li>
                            <button type="button" class="btn btn-danger navbar-btn">管理</button>
                        </li>
                    </ul>
                </div><!-- /.navbar-collapse -->
            </div><!-- /.container-fluid -->
        </nav>
    </div>
{% endblock %}




{% block crticle %}
    <div class="article">
        {% for foo in article_set %}
            <div style="margin-top: 20px">
                <h4 class="media-heading"><a href="">{{ foo.title }}</a></h4>
                <hr>
                <div class="media">
                    <div class="media-body">
                        <h4 class="media-heading">{{ foo.desc }}</h4>
                    </div>
                </div>

                <div class="" style="margin-top: 20px">
                    <span
                            style="padding: 10px;font-size: 13px">{{ foo.blog.userinfo.username }}</span>
                    <span style="padding: 5px;font-size: 13px">{{ foo.create_time|date:'Y-m-d H:s' }}</span>
                    <span style="padding: 5px;font-size: 13px"><i class="fa fa-thumbs-o-up"
                                                                  aria-hidden="true"></i>{{ foo.up_num }}</span>
                    <span style="padding: 10px;font-size: 13px"><i class="fa fa-thumbs-o-down"
                                                                   aria-hidden="true"></i>{{ foo.down_num }}</span>
                    <span style="padding: 10px;font-size: 13px"><i class="fa fa-commenting"
                                                                   aria-hidden="true"></i>{{ foo.comment_num }}</span>
                </div>
            </div>

        {% endfor %}

    </div>
{% endblock %}

标签、分类、随便档案过滤

urls.py

# jasper/tag/4.html 标签匹配
path('<str:name>/tag/<int:tag>.html', views.site),
# jasper/classify/3.html
path('<str:name>/classify/<int:classify>.html', views.site),
# jasper/archive/202209.html
path('<str:name>/archive/<int:time>.html', views.site),

views.py

def site(request, name, **kwargs):
	# name是传过来的站点对应的用户名
    user = UserInfo.objects.filter(username=name).first()
    if not user:
    	# 博主不存在 返回错误界面
        return render(request, 'error.html')
    # 查询该博主的所有文章
    article_set = user.blog.article_set.all()
    # 取名字后的路由后缀
    tag = kwargs.get('tag')
    classify = kwargs.get('classify')
    time = kwargs.get('time')
    # 有tag后缀
    if tag:
    	# 返回当前标签的所有文章
        article_set = article_set.filter(tag__id=tag)
    elif classify:
        article_set = article_set.filter(classify__id=classify)
    # 按时间分类
    elif time:
        year = str(time)[:4]
        month = str(time)[4:]
        article_set = article_set.filter(create_time__year=year, create_time__month=month)
    # # 需要标签名和统计标签内文章数
    classify_res = Classify.objects.all().filter(blog=user.blog).values('id').annotate(
        c=Count('article__id')).values_list('id', 'name', 'c')
    tag_res = Tag.objects.all().filter(blog=user.blog).values('id').annotate(c=Count('article__id')).values_list(
        'id', 'name', 'c')
    date_res = Article.objects.all().filter(blog=user.blog).annotate(year_month=TruncMonth('create_time')).values(
        'year_month').annotate(c=Count('id')).values_list('year_month', 'c')
    return render(request, 'site.html', locals())

官网提供

官网提供了针对日期字段的切割处理

id  content      create_time     month
1   111        2020-11-11     2020-11
2   222        2020-11-12     2020-11
3   333        2020-11-13     2020-11
4   444        2020-11-14     2020-11
5   555        2020-11-15     2020-11
"""
django官网提供的一个orm语法
 from django.db.models.functions import TruncMonth
-官方提供
   from django.db.models.functions import TruncMonth
   Sales.objects
   .annotate(month=TruncMonth('timestamp'))  # Truncate to month and add to select list
   .values('month')  # Group By month
   .annotate(c=Count('id'))  # Select the count of the grouping
   .values('month', 'c')  # (might be redundant, haven't tested) select month and count
   
   
时区问题报错
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
"""
posted @   吴仁耀  阅读(75)  评论(3编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
  1. 1 原来你也在这里 周笔畅
  2. 2 世间美好与你环环相扣 柏松
  3. 3 起风了 吴青峰
  4. 4 极恶都市 夏日入侵企划
世间美好与你环环相扣 - 柏松
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 尹初七

作曲 : 柏松

编曲 : 彭圣杰

偏偏秉烛夜游

偏偏秉烛夜游

午夜星辰 似奔走之友

爱你每个结痂伤口

酿成的陈年烈酒

入喉尚算可口

入喉尚算可口

怎么泪水 还偶尔失守

邀你细看心中缺口

裂缝中留存 温柔

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

知道你不能 还要你感受

知道你不能 还要你感受

让星光加了一点彩虹

让樱花偷偷 吻你额头

让世间美好 与你环环相扣

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

此时已莺飞草长 爱的人正在路上

此时已莺飞草长 爱的人正在路上

我知他风雨兼程 途经日暮不赏

穿越人海 只为与你相拥

此刻已皓月当空 爱的人手捧星光

我知他乘风破浪 去了黑暗一趟

感同身受 给你救赎热望

知道你不能 还要你感受

知道你不能 还要你感受

让星光加了一点彩虹

当樱花开的纷纷扬扬

当世间美好 与你环环相扣

特别鸣谢:槿葵,我们的海报制作妹妹。

原唱:柏松

吉他:柏松

和声:柏松

录音:柏松

混音:张强

点击右上角即可分享
微信分享提示