一、博客系统分析

数据库的构建

首先,我们分析一个博客系统的功能:

  • 一个博客可以有多个标签(多对多)
  • 一个博客可以有多条评论(一对多)
  • 一个博客只可以有一个类别(多对一)

接下来,我们分析关系的属性:

博客:标题,作者,内容,发布时间,分类(外键),标签(多对多)等

标签:标签名

类别:分类名

评论:作者,博客(外键),邮箱,内容,发布时间等。

有8张表,表关系如下:

Day80 博客系统分析,博客主页展示 - 图1

图中箭头开始的英文字母表示关联字段

按照箭头方向查询,表示正向查询,否则为反向查询

新建项目cnblog,应用名为blog

修改models.py,必须导入模块

  1. from django.contrib.auth.models import AbstractUser

因为有一个表userinfo需要继承它。django自带的auth_user表也是继承AbstractUser

表模型如下:

  1. from django.db import models
  2. # Create your models here.
  3. from django.db import models
  4. # Create your models here.
  5. from django.contrib.auth.models import AbstractUser
  6. class UserInfo(AbstractUser):
  7. """
  8. 用户信息
  9. """
  10. nid = models.AutoField(primary_key=True)
  11. telephone = models.CharField(max_length=11, null=True, unique=True)
  12. avatar = models.FileField(upload_to='avatars/', default="avatars/default.png")
  13. create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
  14. blog = models.OneToOneField(to='Blog', to_field='nid', null=True, on_delete=models.CASCADE)
  15. def __str__(self):
  16. return self.username
  17. class Blog(models.Model):
  18. """
  19. 博客信息
  20. """
  21. nid = models.AutoField(primary_key=True)
  22. title = models.CharField(verbose_name='个人博客标题', max_length=64)
  23. site_name = models.CharField(verbose_name='站点名称', max_length=64)
  24. theme = models.CharField(verbose_name='博客主题', max_length=32)
  25. def __str__(self):
  26. return self.title
  27. class Category(models.Model):
  28. """
  29. 博主个人文章分类表
  30. """
  31. nid = models.AutoField(primary_key=True)
  32. title = models.CharField(verbose_name='分类标题', max_length=32)
  33. blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid', on_delete=models.CASCADE)
  34. def __str__(self):
  35. return self.title
  36. class Tag(models.Model):
  37. nid = models.AutoField(primary_key=True)
  38. title = models.CharField(verbose_name='标签名称', max_length=32)
  39. blog = models.ForeignKey(verbose_name='所属博客', to='Blog', to_field='nid', on_delete=models.CASCADE)
  40. def __str__(self):
  41. return self.title
  42. class Article(models.Model):
  43. nid = models.AutoField(primary_key=True)
  44. title = models.CharField(max_length=50, verbose_name='文章标题')
  45. desc = models.CharField(max_length=255, verbose_name='文章描述')
  46. create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
  47. content = models.TextField()
  48. comment_count = models.IntegerField(default=0)
  49. up_count = models.IntegerField(default=0)
  50. down_count = models.IntegerField(default=0)
  51. user = models.ForeignKey(verbose_name='作者', to='UserInfo', to_field='nid', on_delete=models.CASCADE)
  52. category = models.ForeignKey(to='Category', to_field='nid', null=True, on_delete=models.CASCADE)
  53. tags = models.ManyToManyField(
  54. to="Tag",
  55. #through参数可以指定用作中介的中间模型
  56. through='Article2Tag',
  57. )
  58. def __str__(self):
  59. return self.title
  60. class Article2Tag(models.Model):
  61. nid = models.AutoField(primary_key=True)
  62. article = models.ForeignKey(verbose_name='文章', to="Article", to_field='nid', on_delete=models.CASCADE)
  63. tag = models.ForeignKey(verbose_name='标签', to="Tag", to_field='nid', on_delete=models.CASCADE)
  64. class Meta:
  65. #组合唯一约束
  66. unique_together = [
  67. ('article', 'tag'),
  68. ]
  69. def __str__(self):
  70. v = self.article.title + "---" + self.tag.title
  71. return v
  72. class ArticleUpDown(models.Model):
  73. """
  74. 点赞表
  75. """
  76. nid = models.AutoField(primary_key=True)
  77. user = models.ForeignKey('UserInfo', null=True, on_delete=models.CASCADE)
  78. article = models.ForeignKey("Article", null=True, on_delete=models.CASCADE)
  79. is_up = models.BooleanField(default=True)
  80. class Meta:
  81. # 组合唯一约束
  82. unique_together = [
  83. ('article', 'user'),
  84. ]
  85. class Comment(models.Model):
  86. """
  87. 评论表
  88. """
  89. nid = models.AutoField(primary_key=True)
  90. article = models.ForeignKey(verbose_name='评论文章', to='Article', to_field='nid', on_delete=models.CASCADE)
  91. user = models.ForeignKey(verbose_name='评论者', to='UserInfo', to_field='nid', on_delete=models.CASCADE)
  92. content = models.CharField(verbose_name='评论内容', max_length=255)
  93. create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
  94. parent_comment = models.ForeignKey('Comment', null=True, on_delete=models.CASCADE)
  95. def __str__(self):
  96. return self.content

相关参数解释:

through 表示orm,不要创建关系表。而制定一个表,这个表自己来创建!为什么呢?因为orm创建多对多关系表时,只有3个字段。那么需要关系表需要扩充字段时,就不行了!

所以设置through 字段,是为了方便添加额外的字段。使用through,那么这个表,称之为中间模型。

在Comment模型表中,有一个字段parent_comment。它关联的是本身表中的主键nid,它是一个父级评论id,用来展示谁评论谁!to=’Comment’等同于to=’self’

修改settings.py配置文件,覆盖默认的User模型****最后一行添加,否则执行创建表命令时会报错!

  1. AUTH_USER_MODEL="blog.UserInfo"

Django允许你通过修改setting.py文件中的 AUTH_USER_MODEL 设置覆盖默认的User模型,其值引用一个自定义的模型。

bolg,是应用名。

使用下面2个命令,生成表

  1. python manage.py makemigrations
  2. python manage.py migrate

生成的表如下:

Day80 博客系统分析,博客主页展示 - 图2

注意:django自带的auth_user表没有了,取而代之的是blog_userinfo表。

查看表字段

Day80 博客系统分析,博客主页展示 - 图3

它在auth_user表的基础上,增加了5个字段!

登录验证

添加超级用户,密码必须是8位或者以上!

  1. python manage.py createsuperuser

效果如下:

Day80 博客系统分析,博客主页展示 - 图4

再创建2个用户,zhang和lisi。用来测试多个用户登录!

Day80 博客系统分析,博客主页展示 - 图5

lisi用户

Day80 博客系统分析,博客主页展示 - 图6

修改urls.py,增加路径

  1. from blog import views
  2. urlpatterns = [
  3. path('admin/', admin.site.urls),
  4. path('index/', views.index),
  5. path('login/', views.login),
  6. ]

修改views.py,增加视图函数

  1. from django.shortcuts import render,HttpResponse,redirect
  2. from django.contrib import auth
  3. from blog.models import Article,UserInfo
  4. # Create your views here.
  5. def login(request):
  6. if request.method=="POST":
  7. user=request.POST.get("user")
  8. pwd=request.POST.get("pwd")
  9. # 用户验证成功,返回user对象,否则返回None
  10. user=auth.authenticate(username=user,password=pwd)
  11. if user:
  12. # 登录,注册session
  13. # 全局变量 request.user=当前登陆对象(session中)
  14. auth.login(request,user)
  15. return redirect("/index/")
  16. return render(request,"login.html")
  17. def index(request):
  18. return render(request,"index.html")

修改login.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <form action="" method="post">
  9. {% csrf_token %}
  10. <lable>用户名</lable><input type="text" name="user">
  11. <lable>密码</lable><input type="password" name="pwd">
  12. <input type="submit">
  13. </form>
  14. </body>
  15. </html>

修改index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <h3>INDEX</h3>
  9. </body>
  10. </html>

访问登录页面

Day80 博客系统分析,博客主页展示 - 图7

跳转到首页

Day80 博客系统分析,博客主页展示 - 图8

首页修饰

修改settings.py,设置静态文件目录。最后一行添加:

  1. STATICFILES_DIRS=[
  2. os.path.join(BASE_DIR,"static")
  3. ]

下载bootsrtap,将压缩的包内容放到satic目录

img和js是新建的

目录如下:

Day80 博客系统分析,博客主页展示 - 图9

修改urls.py,增加路径

  1. urlpatterns = [
  2. path('admin/', admin.site.urls),
  3. path('login/', views.login),
  4. path('index/', views.index),
  5. path('logout/', views.logout),
  6. path('', views.index),
  7. ]

修改views.py,增加注销

  1. def logout(request): # 注销
  2. auth.logout(request)
  3. return redirect("/index/")

修改index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
  7. <script src="/static/js/jquery.js"></script>
  8. <script src="/static/bootstrap/js/bootstrap.js"></script>
  9. <style>
  10. .desc{
  11. text-align: justify;
  12. }
  13. .info{
  14. margin-top: 10px;
  15. }
  16. </style>
  17. </head>
  18. <body>
  19. <nav class="navbar navbar-default">
  20. <div class="container-fluid">
  21. <!-- Brand and toggle get grouped for better mobile display -->
  22. <div class="navbar-header">
  23. <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
  24. data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
  25. <span class="sr-only">Toggle navigation</span>
  26. <span class="icon-bar"></span>
  27. <span class="icon-bar"></span>
  28. <span class="icon-bar"></span>
  29. </button>
  30. <a class="navbar-brand" href="#">博客园</a>
  31. </div>
  32. <!-- Collect the nav links, forms, and other content for toggling -->
  33. <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
  34. <ul class="nav navbar-nav">
  35. <li class="active"><a href="#">新闻 <span class="sr-only">(current)</span></a></li>
  36. <li><a href="#">博问</a></li>
  37. </ul>
  38. <ul class="nav navbar-nav navbar-right">
  39. {% if request.user.username %}
  40. <li><a href="#"><span class="glyphicon glyphicon-user"></span> {{ request.user.username }}</a>
  41. </li>
  42. <li class="dropdown">
  43. <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
  44. aria-expanded="false">Dropdown <span class="caret"></span></a>
  45. <ul class="dropdown-menu">
  46. <li><a href="#">修改密码</a></li>
  47. <li><a href="#">个人信息</a></li>
  48. <li><a href="/logout/">注销</a></li>
  49. <li role="separator" class="divider"></li>
  50. <li><a href="#">Separated link</a></li>
  51. </ul>
  52. </li>
  53. {% else %}
  54. <li><a href="/login/">登陆</a></li>
  55. <li><a href="#">注册</a></li>
  56. {% endif %}
  57. </ul>
  58. </div><!-- /.navbar-collapse -->
  59. </div><!-- /.container-fluid -->
  60. </nav>
  61. <div class="container-fluid">
  62. <div class="row">
  63. <div class="col-md-3">
  64. <div class="panel panel-primary">
  65. <div class="panel-heading">
  66. <h3 class="panel-title">Panel title</h3>
  67. </div>
  68. <div class="panel-body">
  69. Panel content
  70. </div>
  71. </div>
  72. <div class="panel panel-danger">
  73. <div class="panel-heading">
  74. <h3 class="panel-title">Panel title</h3>
  75. </div>
  76. <div class="panel-body">
  77. Panel content
  78. </div>
  79. </div>
  80. </div>
  81. <div class="col-md-6">
  82. 222
  83. </div>
  84. <div class="col-md-3">
  85. <div class="panel panel-warning">
  86. <div class="panel-heading">
  87. <h3 class="panel-title">Panel title</h3>
  88. </div>
  89. <div class="panel-body">
  90. Panel content
  91. </div>
  92. </div>
  93. <div class="panel panel-info">
  94. <div class="panel-heading">
  95. <h3 class="panel-title">Panel title</h3>
  96. </div>
  97. <div class="panel-body">
  98. Panel content
  99. </div>
  100. </div>
  101. <div class="panel panel-success">
  102. <div class="panel-heading">
  103. <h3 class="panel-title">Panel title</h3>
  104. </div>
  105. <div class="panel-body">
  106. Panel content
  107. </div>
  108. </div>
  109. </div>
  110. </div>
  111. </div>
  112. </body>
  113. </html>

重新登录,效果如下:

Day80 博客系统分析,博客主页展示 - 图10

添加内容

使用django自带的admin后台,快速添加数据。

访问后台页面,这里必须是超级用户。上面已经创建了超级用户xiao

默认是空的

Day80 博客系统分析,博客主页展示 - 图11

操作表,必须要注册

修改views.py同级目录下的admin.py

注册所有的模型表

from django.contrib import admin

# Register your models here.

from blog import models

admin.site.register(models.UserInfo)
admin.site.register(models.Blog)
admin.site.register(models.Category)
admin.site.register(models.Tag)
admin.site.register(models.Article2Tag)
admin.site.register(models.Article)
admin.site.register(models.ArticleUpDown)
admin.site.register(models.Comment)

再次刷新页面

Day80 博客系统分析,博客主页展示 - 图12

点击Articles,添加文章

Day80 博客系统分析,博客主页展示 - 图13

http://www.py3study.com 上面copy一篇博客

注意内容都是html代码

Day80 博客系统分析,博客主页展示 - 图14

添加分类

Day80 博客系统分析,博客主页展示 - 图15

添加站点

Day80 博客系统分析,博客主页展示 - 图16

保存

Day80 博客系统分析,博客主页展示 - 图17

点击保存

Day80 博客系统分析,博客主页展示 - 图18

添加成功

Day80 博客系统分析,博客主页展示 - 图19

多添加几篇博客

Day80 博客系统分析,博客主页展示 - 图20

首页文章展示

修改settings.py,更改时区

TIME_ZONE = 'Asia/Shanghai'

修改index视图函数

def index(request):
    article_list=Article.objects.all()
    return render(request,"index.html",{"article_list":article_list})

修改index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery.js"></script>
    <script src="/static/bootstrap/js/bootstrap.js"></script>
    <style>
        .desc{
            text-align: justify;
        }

        .info{
            margin-top: 10px;
        }

    </style>
</head>
<body>
<nav class="navbar navbar-default">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <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">
                {% if request.user.username %}
                    <li><a href="#"><span class="glyphicon glyphicon-user"></span> {{ request.user.username }}</a>
                    </li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                           aria-expanded="false">Dropdown <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#">修改密码</a></li>
                            <li><a href="#">个人信息</a></li>
                            <li><a href="/logout/">注销</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="#">Separated link</a></li>
                        </ul>
                    </li>

                {% else %}
                    <li><a href="/login/">登陆</a></li>
                    <li><a href="#">注册</a></li>
                {% endif %}


            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>

<div class="container-fluid">
    <div class="row">
        <div class="col-md-3">
            <div class="panel panel-primary">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>

            <div class="panel panel-danger">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
        </div>
        <div class="col-md-6">

            <div class="article_list">
                {% for article in article_list %}
                 <div class="article_item">
                      <h5><a href="">{{ article.title }}</a></h5>
                      <div>
                          <span class="media-left"><a href=""><img width="60" height="60" src="https://ss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=1758343206,1224786249&fm=58&bpow=1024&bpoh=1536" alt=""></a></span>

                          <span class="media-right small desc ">
                              {{ article.desc }}
                          </span>

                      </div>
                      <div class="info small">
                            <span><a href="">{{ article.user.username }}</a></span>  
                            发布于 <span>{{ article.create_time|date:'Y-m-d H:i' }}</span>  
                           <span class="glyphicon glyphicon-comment"></span><a href="">评论({{ article.comment_count }})</a>  
                           <span class="glyphicon glyphicon-thumbs-up"></span><a href="">点赞({{ article.up_count }})</a>
                      </div>
                 </div>
                    <hr>
                {% endfor %}
            </div>



        </div>
        <div class="col-md-3">

            <div class="panel panel-warning">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
            <div class="panel panel-info">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
            <div class="panel panel-success">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>

        </div>
    </div>
</div>

</body>
</html>

访问首页,效果如下:

Day80 博客系统分析,博客主页展示 - 图21

个人站点展示

比如博客园范围个人站点是域名加用户名,就可以了,比如:

https://www.cnblogs.com/xiao987334176

如果用户不存在,会提示404页面

增加404页面

修改urls.py,增加路径。注意导入re_path

from django.contrib import admin
from django.urls import path,re_path
from blog import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/', views.login),
    path('index/', views.index),
    path('logout/', views.logout),
    path('', views.index),
    re_path('(?P<username>\w+)', views.homesite),
]

修改views.py,增加视图函数

def homesite(request,username):
    """
    查询
    :param request:
    :param username:
    :return:
    """

    # 查询当前站点的用户对象
    user=UserInfo.objects.filter(username=username).first()
    if not user:
        return render(request,"not_found.html")

    return render(request,"homesite.html",{"user":user})

在templates目录创建文件not_found.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
</head>
<body>


<div class="container" style="margin-top: 100px">
    <div class="text-center">
        <a href="http://www.cnblogs.com/"><img src="/static/img/logo_small.gif" alt="cnblogs"></a>
        <p><b>404.</b> 抱歉! 您访问的资源不存在!</p>
        <p class="d">请确认您输入的网址是否正确,如果问题持续存在,请发邮件至 xx@qq.com 与 <strong style="font-size: 28px">xiao</strong> 联系。</p>
        <p><a href="/">返回网站首页</a></p>

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

创建homesite.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>{{ user }}</h3>
</body>
</html>

访问网页:http://127.0.0.1:8000/xiao

Day80 博客系统分析,博客主页展示 - 图22

访问一个不存在的用户

http://127.0.0.1:8000/123

页面提示404

Day80 博客系统分析,博客主页展示 - 图23

展示文章列表

修改homesite视图函数

def homesite(request,username):
    """
    查询
    :param request:
    :param username:
    :return:
    """

    # 查询当前站点的用户对象
    user=UserInfo.objects.filter(username=username).first()
    if not user:
        return render(request,"not_found.html")
    # 查询当前站点对象
    blog=user.blog

    # 查询当前用户发布的所有文章
    article_list=Article.objects.filter(user__username=username)

    return render(request,"homesite.html",{"blog":blog,"article_list":article_list})

修改homesite.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .header{
            width: 100%;
            height: 59px;
            background-color: #369;
        }
        .header .title{
            line-height: 59px;
            color: white;
            font-weight: lighter;
            margin-left: 20px;
            font-size: 18px;
        }

        .left_region{
            margin-top: 10px;
        }

        .info{
          margin-top: 10px;
          color: darkgray;

        }
    </style>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery.js"></script>
    <script src="/static/bootstrap/js/bootstrap.js"></script>
</head>
<body>
<div class="header">
    <p class="title">{{ blog.title }}</p>
</div>


<div class="container-fluid">
    <div class="row">
        <div class="col-md-3">
            <div class="left_region">
                 <div class="panel panel-success">
                <div class="panel-heading">
                    <h3 class="panel-title">Panel title</h3>
                </div>
                <div class="panel-body">
                    Panel content
                </div>
            </div>
                 <div class="panel panel-warning">
                    <div class="panel-heading">
                        <h3 class="panel-title">Panel title</h3>
                    </div>
                    <div class="panel-body">
                        Panel content
                    </div>
                </div>
                 <div class="panel panel-info">
                    <div class="panel-heading">
                        <h3 class="panel-title">Panel title</h3>
                    </div>
                    <div class="panel-body">
                        Panel content
                    </div>
                </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>

                          <span class="small desc ">
                              {{ article.desc }}
                          </span>

                      </div>
                      <div class="info small pull-right">
                            发布于 <span>{{ article.create_time|date:'Y-m-d H:i' }}</span>  
                           <span class="glyphicon glyphicon-comment"></span><a href="">评论({{ article.comment_count }})</a>  
                           <span class="glyphicon glyphicon-thumbs-up"></span><a href="">点赞({{ article.up_count }})</a>
                      </div>
                 </div>
                    <hr>
                {% endfor %}
            </div>

        </div>
    </div>
</div>


</body>
</html>

访问xiao的个人站点,效果如下:

Day80 博客系统分析,博客主页展示 - 图24

这个时候发现,左上角没有显示博客标题。那是因为用户认证表的blog_id字段默认为空,需要在admin后台绑定一下

登录到后台,点击用户表,点击指定的用户xiao

拉到最下面,绑定blog,点击保存

Day80 博客系统分析,博客主页展示 - 图25

再次刷新个人站点,发现出来了!

Day80 博客系统分析,博客主页展示 - 图26

作业:

查询当前站点每一个分类的名称以及对应的文章数

查询当前站点每一个标签的名称以及对应的文章数

答案:

修改homesite视图函数

def homesite(request,username):
    """
    查询
    :param request:
    :param username:
    :return:
    """
    # 查询当前站点的用户对象
    user=UserInfo.objects.filter(username=username).first()
    if not user:
        return render(request,"not_found.html")
    # 查询当前站点对象

    blog=user.blog

    # 查询当前用户发布的所有文章
    article_list=Article.objects.filter(user__username=username)

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

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

    dict = {"blog":blog,
            "article_list":article_list,
            "category_count":cate_list,
            "tag_count":tag_list,
            }

    return render(request,"homesite.html",dict)

修改homesite.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .header{
            width: 100%;
            height: 59px;
            background-color: #369;
        }
        .header .title{
            line-height: 59px;
            color: white;
            font-weight: lighter;
            margin-left: 20px;
            font-size: 18px;
        }

        .left_region{
            margin-top: 10px;
        }

        .info{
          margin-top: 10px;
          color: darkgray;

        }
        h5 a {
            color: #105cb6;
            font-size: 14px;
            font-weight: bold;
            text-decoration: underline;
        }

    </style>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery.js"></script>
    <script src="/static/bootstrap/js/bootstrap.js"></script>
</head>
<body>
<div class="header">
    <p class="title">{{ blog.title }}</p>
</div>


<div class="container-fluid">
    <div class="row">
        <div class="col-md-3">
            <div class="left_region">
                 <div class="panel panel-success">
                <div class="panel-heading">
                    <h3 class="panel-title">我的标签</h3>
                </div>
                     {% for foo in category_count %}
                         <div class="panel-body">
                    {{ foo.title }}({{ foo.c }})
                </div>

                     {% endfor %}

            </div>
                 <div class="panel panel-warning">
                    <div class="panel-heading">
                        <h3 class="panel-title">随笔分类</h3>
                    </div>
                     {% for foo in tag_count %}
                         <div class="panel-body">
                    {{ foo.title }}({{ foo.c }})
                </div>

                     {% endfor %}

                </div>
                 <div class="panel panel-info">
                    <div class="panel-heading">
                        <h3 class="panel-title">随笔档案</h3>
                    </div>
                    <div class="panel-body">
                        Panel content
                    </div>
                </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>

                          <span class="small desc ">
                              {{ article.desc }}
                          </span>

                      </div>
                      <div class="info small pull-right">
                            发布于 <span>{{ article.create_time|date:'Y-m-d H:i' }}</span>  
                           <img src="/static/img/icon_comment.gif" alt=""><a href="">评论({{ article.comment_count }})</a>  
                           <span class="glyphicon glyphicon-thumbs-up"></span><a href="">点赞({{ article.up_count }})</a>
                      </div>
                 </div>
                    <hr>
                {% endfor %}
            </div>

        </div>
    </div>
</div>


</body>
</html>

进入admin后台,添加一个tag。增加一篇文章

Day80 博客系统分析,博客主页展示 - 图27

重新访问个人站点网页,效果如下:

Day80 博客系统分析,博客主页展示 - 图28