django博客项目-个人站点页面设计

本文详细介绍了如何构建个人站点并实现文章、分类、标签和归档的查询功能。通过Django的ORM查询,实现了根据用户名获取用户文章,统计分类和标签下的文章数量,以及按年月归档的文章数。同时,前端页面使用Bootstrap布局,展示了左侧的分类、标签和归档,右侧则显示文章列表,并实现了分类和归档的跳转功能。
摘要由CSDN通过智能技术生成

查询当前站点的所有文章

进入某一个用户的站点是以https://www.cnblogs.com/用户名的形式访问,我们设计url仿照此设计。
站点和用户是一对一关系,查询站点所有文章也就是查询对应用户写的所有文章。

代码

后端代码:
urls.py

# 个人站点
url(r'^(?P<username>\w+)$', blog_views.home_site),

views.py

def home_site(request, username):
    user = UserInfo.objects.filter(username=username).first()
    # 判断用户是否存在
    if not user:
        # 返回404
        return render(request, 'not_found.html')

    # 查询出当前用户对应的站站点信息
    blog = user.blog

    # 基于对象的所有文章查询
    # article_list = user.article_set.all()
    # 基于 __ 查询
    article_list = models.Article.objects.filter(user=user)
    print(article_list)

    return render(request, 'home_site.html')

知识点

ORM查询

查询当前站点标签、分类、日期查询

##代码
后端代码:

def home_site(request, username):
    user = UserInfo.objects.filter(username=username).first()
    # 判断用户是否存在
    if not user:
        # 返回404
        return render(request, 'not_found.html')

    # 查询出当前用户对应的站站点信息
    blog = user.blog

    # 基于对象的所有文章查询
    # article_list = user.article_set.all()
    # 基于 __ 查询
    article_list = models.Article.objects.filter(user=user)
    # print(article_list)

    # 查询当前站点每一个分类名称以及对应的文章数
    res = models.Category.objects.annotate(num=Count('article__title')).values('title', 'num')
    print(res)
    category_list = models.Category.objects.filter(blog=blog).annotate(c=Count('article__title')).values('title', 'c')
    print(category_list)

    # 查询当前站点每一个标签名称以及对应的文章数
    tag_list = models.Tag.objects.filter(blog=blog).annotate(c=Count('article__title')).values('title', 'c')
    print(tag_list)


    # 查询当前每一个站点每一个年月的名称以及对应的文章数(单表分组查询)
    # 方式一:
    # date_list = models.Article.objects.filter(user=user).extra(select={'y_m_date':'strftime("%%Y-%%m", create_time)'}).\
    #     values('title','y_m_date').annotate(c=Count('pk')).values('y_m_date', 'c')

    # 方式二:
    from django.db.models.functions import TruncMonth
    date_list = models.Article.objects.filter(user=user).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('pk')).\
        values('month', 'c')
    print(date_list)

    return render(request, 'home_site.html')

知识点

分组查询
单表分组查询
extra函数使用
mysql对应的dateformat
sqlite对应的strftime
TrauncMonth的使用

个人站点布局渲染

个人站点分为左右两栏,左侧显示归档信息,右侧显示文章列表。

代码

前端代码:home_site.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <script src="/static/js/jquery.min.js"></script>
    <script src="/static/js/bootstrap.min.js"></script>
    <style>
        *{
            margin: 0;
            padding: 0
        }
        .header{
            width:100%;
            height:60px;
            background-color: #369;
        }
        .header .title{
            font-size: 18px;
            font-weight: 100;
            line-height: 60px;
            color: white;
            margin-left: 15px;
            margin-top: -10px;
        }
        .backend{
            float:right;
            color:white;
            text-decoration: none;
            margin-right:10px;
            margin-top:10px;
        }
        .pub_info{
            margin-top:10px;
            color:dark-green;
        }
    </style>
</head>
<body>
<div class="header">
    <div class="content">
        <p class="title">
            <span class="">{{ blog.title }}</span>
            <a href="" class="backend">管理</a>
        </p>
    </div>
</div>
<div class="container">
    <div class="row">
        <div class="col-md-3">
            <div class="panel panel-warning">
                <div class="panel-heading">我的标签</div>
                <div class="panel-body">
                    {% for tag in tag_list %}
                        <p>{{ tag.title }}({{ tag.c }})</p>
                    {% endfor %}
                </div>
            </div>
            <div class="panel panel-danger">
                <div class="panel-heading">我的分类</div>
                <div class="panel-body">
                    {% for category in category_list %}
                        <p>{{ category.title }}({{ category.c }})</p>
                    {% endfor %}
                </div>
            </div>
            <div class="panel panel-info">
                <div class="panel-heading">随笔归档</div>
                <div class="panel-body">
                    {% for date in date_list %}
                        <p>{{ date.month|date:'Y-m' }}({{ date.c }})</p>
                    {% endfor %}
                </div>
            </div>
        </div>
        <div class="col-md-9">
            <div class="article_list">
                {% for article in article_list %}
                <div class="article_item clearfix">
                    <h5><a href="">{{ article.title }}</a></h5>
                    <div class="article-desc">
                        {{ article.desc }}
                    </div>
                    <div class="small pub_info pull-right">
                        <span><a href="">{{ article.user.username }}</a></span>&nbsp;&nbsp;
                        <span>发布于&nbsp;&nbsp;{{ article.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;&nbsp;
                        <span class="glyphicon glyphicon-comment"></span>评论({{ article.comment_count }})&nbsp;&nbsp;
                        <span class="glyphicon glyphicon-thumbs-up"></span>点赞({{ article.up_count }})
                    </div>

                </div>
                <hr>
                {% endfor %}
            </div>
        </div>
    </div>
</div>
</body>
</html>

知识点

前端样式编写

效果展示

在这里插入图片描述

页面跳转过滤

标签分类归档下的跳转功能,点击我的分类下的某一个分类,文章列表显示对应的分类文章。

代码

前端代码:home_site.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/bootstrap.min.css">
    <script src="/static/js/jquery.min.js"></script>
    <script src="/static/js/bootstrap.min.js"></script>
    <style>
        *{
            margin: 0;
            padding: 0
        }
        .header{
            width:100%;
            height:60px;
            background-color: #369;
        }
        .header .title{
            font-size: 18px;
            font-weight: 100;
            line-height: 60px;
            color: white;
            margin-left: 15px;
            margin-top: -10px;
        }
        .backend{
            float:right;
            color:white;
            text-decoration: none;
            margin-right:10px;
            margin-top:10px;
            font-size:14px;
        }
        .pub_info{
            margin-top:10px;
            color:dark-green;
        }
    </style>
</head>
<body>
<div class="header">
    <div class="content">
        <p class="title">
            <span class="">{{ blog.title }}</span>
            <a href="" class="backend">管理</a>
        </p>
    </div>
</div>
<div class="container">
    <div class="row">
        <div class="col-md-3">
            <div class="panel panel-warning">
                <div class="panel-heading">我的标签</div>
                <div class="panel-body">
                    {% for tag in tag_list %}
                        <p><a href="/{{ username }}/tag/{{ tag.title }}/">{{ tag.title }}({{ tag.c }})</a></p>
                    {% endfor %}
                </div>
            </div>
            <div class="panel panel-danger">
                <div class="panel-heading">我的分类</div>
                <div class="panel-body">
                    {% for category in category_list %}
                        <p><a href="/{{ username }}/category/{{ category.title }}/">{{ category.title }}({{ category.c }})</a></p>
                    {% endfor %}
                </div>
            </div>
            <div class="panel panel-info">
                <div class="panel-heading">随笔归档</div>
                <div class="panel-body">
                    {% for date in date_list %}
                    <p><a href="/{{ username }}/archive/{{ date.month|date:'Y-m' }}/">{{ date.month|date:'Y-m' }}({{ date.c }})</a></p>
                    {% endfor %}
                </div>
            </div>
        </div>
        <div class="col-md-9">
            <div class="article_list">
                {% for article in article_list %}
                <div class="article_item clearfix">
                    <h5><a href="">{{ article.title }}</a></h5>
                    <div class="article-desc">
                        {{ article.desc }}
                    </div>
                    <div class="small pub_info pull-right">
                        <span><a href="">{{ article.user.username }}</a></span>&nbsp;&nbsp;
                        <span>发布于&nbsp;&nbsp;{{ article.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;&nbsp;
                        <span class="glyphicon glyphicon-comment"></span>评论({{ article.comment_count }})&nbsp;&nbsp;
                        <span class="glyphicon glyphicon-thumbs-up"></span>点赞({{ article.up_count }})
                    </div>

                </div>
                <hr>
                {% endfor %}
            </div>
        </div>
    </div>
</div>
</body>
</html>

后端代码:

# urls.py
from django.conf.urls import url
from django.contrib import admin
from django.views.static import serve
from cnblog import settings
from blog import views as blog_views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', blog_views.index),
    url(r'^login/', blog_views.login, name="login"),
    url(r'^logout/', blog_views.logout, name="logout"),
    url(r'^register', blog_views.register, name="register"),
    url(r'^index/', blog_views.index, name="index"),
    url(r'^get_validCode_img', blog_views.get_validCode_img),

    # media 配置
    url(r'media/(?P<path>.*)$', serve, {"document_root": settings.MEDIA_ROOT}),

    # 个人站点
    url(r'^(?P<username>\w+)/$', blog_views.home_site),

    # 个人站点跳转
    url(r'^(?P<username>\w+)/(?P<condition>tag|category|archive)/(?P<param>.*)/$', blog_views.home_site),
]
# views.py
def home_site(request, username, **kwargs):
    user = UserInfo.objects.filter(username=username).first()
    # 判断用户是否存在
    if not user:
        # 返回404
        return render(request, 'not_found.html')

    # 查询出当前用户对应的站站点信息
    blog = user.blog

    # 基于对象的所有文章查询
    # article_list = user.article_set.all()
    # 基于 __ 查询
    article_list = models.Article.objects.filter(user=user)
    if kwargs:
        condition = kwargs.get('condition')
        param = kwargs.get('param')

        if condition == 'category':
            # article_list = models.Article.objects.filter(user=user, category__title=param)
            article_list = article_list.filter(category__title=param)
        elif condition == 'tag':
            # article_list = models.Article.objects.filter(user=user, tags__title=param)
            article_list = article_list.filter(tags__title=param)
        elif condition == 'archive':
            year, month = param.split('-')
            print(year, month)
            # article_list = models.Article.objects.filter(
            #     user=user,
            #     create_time__year=year,
            #     create_time__month=month
            # )
            article_list = article_list.filter(create_time__year=year, create_time__month=month)
        else:
            pass



    # print(article_list)

    # 查询当前站点每一个分类名称以及对应的文章数
    # res = models.Category.objects.annotate(num=Count('article__title')).values('title', 'num')
    # print(res)
    category_list = models.Category.objects.filter(blog=blog).annotate(c=Count('article__title')).values('title', 'c')
    print(category_list)

    # 查询当前站点每一个标签名称以及对应的文章数
    tag_list = models.Tag.objects.filter(blog=blog).annotate(c=Count('article__title')).values('title', 'c')
    print(tag_list)


    # 查询当前每一个站点每一个年月的名称以及对应的文章数(单表分组查询)
    # 方式一:
    # date_list = models.Article.objects.filter(user=user).extra(select={'y_m_date':'strftime("%%Y-%%m", create_time)'}).\
    #     values('title','y_m_date').annotate(c=Count('pk')).values('y_m_date', 'c')

    # 方式二:
    from django.db.models.functions import TruncMonth
    date_list = models.Article.objects.filter(user=user).annotate(month=TruncMonth('create_time')).values('month').annotate(c=Count('pk')).\
        values('month', 'c')
    print(date_list)

    return render(request, 'home_site.html', locals())

知识点

url路由匹配设计

效果展示

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值