BBS的个人主页,文章详情页以及模板继承,数据库关联查询操作

上一篇文章我们写好了主页面(index),现在我们要从主页面跳转到个人用户的个人页面.

个人页面

首先在主页面实现跳转

<span><a
                                        href="/blog/{{ foo.user.username }}"
                                        id="id_span">{{ foo.user.username }}</a></span>

给username加一个a标签,为了实现点击头像也能跳转,在头像那边加一个label标签

<label for="id_span"><a
                                            href="/blog/{{ foo.user.username }}" id="id_span">
                                        <img class="media-object author-img img-circle"
                                             src="/media/{{ foo.user.avatar }}" alt="头像">
                                    </a>
                                    </label>

label标签的for关键字与a标签的id关联.

设置url,写视图函数,在视图函数里,接受username参数
技术点:
1.归档的数据库查询

def home(request,username):
    print(username)
    # 去usernameInfo表中把用户对象取出来
    user = models.UserInfo.objects.filter(username = username).first()
    if not user:
        print(444)
        return HttpResponse("404")
    else:
        # 如果用户存在需要将他写的所有文章取出来
        blog = user.blog

        # article_list查询,我的文章列表
        article_list = models.Article.objects.filter(user=user)

        # 我的文章分类,及每个分类下的文章数
        # 将我的文章按照我的分类分组,并统计出每个分类下的文章数
        category_list = models.Category.objects.filter(blog=blog)
        # 统计当前站点下有哪些标签
        # 看当前博客下有什么标签,反向查询article表,values("title","c")看tag.title下的文章数
        tag_list = models.Tag.objects.filter(blog=blog).annotate(c=Count("article")).values("title","c")
        # 按照日期归档
        archive_list = models.Article.objects.filter(user=user).extra(
            select={"archive_ym":"date_format(create_time,'%%Y-%%m')"}
        ).values("archive_ym").annotate(c=Count("nid")).values("archive_ym","c")
        return render(request,'home.html',
                      {"blog":blog,
                       "article_list":article_list,
                       "category_list":category_list,
                       "tag_list":tag_list,
                       "archive_list":archive_list,})

base.html

base.html是用于继承的,因为个人页面和文章详情页面都有一些相同的地方比如右边的归档,所以,把这些相同的页面放在base里
技术点:
1.3-8布局
2.从后台拿到的数据用for循环渲染到前端
3.定义块,其他页面的继承的时候先写块.

  {% block page-main %}

    {% endblock %}`
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ username }}的个人博客</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/fontawesome/css/font-awesome.min.css">
    <link rel="stylesheet" href="/static/mystyle.css">
    <link rel="stylesheet" href="/static/theme/{{ blog.theme }}">
</head>
<body>
<div class="header">
    <p>{{ blog.title }}</p>
</div>
<div class="container">
    <div class="col-md-3">
        <div class="panel panel-primary">
            <div class="panel-heading">文章分类</div>
            {% for category in category_list %}
                <div class="panel-body">
                    <p>{{ category.title }}({{ category.article_set.all.count }})</p>

                </div>
            {% endfor %}


        </div>
        <div class="panel panel-warning">
            <div class="panel-heading">文章标签</div>
            {% for tag in tag_list %}
                <div class="panel-body">
                    <p>{{ tag.title }}({{ tag.c }})</p>

                </div>
            {% endfor %}


        </div>
    <div class="panel panel-warning">
            <div class="panel-heading">日期归档</div>
            {% for tag in archive_list %}
                <div class="panel-body">
                    <p>{{ tag.archive_ym }}({{ tag.c }})</p>

                </div>
            {% endfor %}


        </div>
    </div>
    <div class="col-md-8">
    {% block page-main %}

    {% endblock %}
        <!--个人博客列表 开始-->

        <!--个人博客列表 结束-->
    </div>
</div>
<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>

个人主页

技术点:
1.先继承,前两句代码
2.其他的部分在index页面有写,copy过来

{% extends 'base.html' %}

{% block page-main %}
 <div class="article-list">
            {% for foo in article_list %}
                <div class="article">
                    <p class="article-title"><a href="{{ foo.user.username }}/article/{{ foo.pk }}">{{ foo.title }}</a></p>
                    <div class="media">
                        <div class="media-left media-middle">
                            <a href="#">
                                <img class="media-object author-img img-circle"
                                     src="/media/{{ foo.user.avatar }}" alt="头像">
                            </a>
                        </div>
                        <div class="media-body">
                            <p>{{ foo.desc }}</p>
                        </div>
                    </div>
                    <div class="article-footer">
                        <span><a href="/blog/{{ foo.user.username }}">{{ foo.user.username }}</a></span>发布于
                        <span>{{ foo.create_time | date:"Y-m-d H:i:s" }}</span>
                        {#                            <span class="glyphicon glyphicon-comment">评论({{ foo.comment_set.all.count }})</span>#}
                        {#                            <span class="glyphicon glyphicon-thumbs-up">点赞({{ foo.articleupdown_set.all.count }})</span>#}
                        <i class="fa fa-comments "
                           aria-hidden="true"><span>评论({{ foo.comment_set.all.count }})</span></i>
                        <i class="fa fa-thumbs-o-up"
                           aria-hidden="true"><span>点赞({{ foo.articleupdown_set.all.count }})</span></i>
                    </div>
                    <hr color="red">
                    {# 分割线 #}
                </div>
            {% endfor %}

        </div>
{% endblock %}

文章详情页

技术点:
1.参数的pk,这里的pk就是指id,不论模型的id名称是什么,只要写pk都行

def article_detail(request,username,username1,pk):
    # pk是文章主键
    article_obj = models.Article.objects.filter(pk=pk).first()
    print(article_obj)
    user = models.UserInfo.objects.filter(username=username).first()
    if not user:
        return HttpResponse("404")
    blog = user.blog
    return render(request,"article_detail.html",{"article":article_obj,"blog":blog})

这里同样继承自base.html,article和articledetail是一对一关系因此可以直接这样引用,要正确显示文章信息要加上safe过滤器.

{% extends 'base.html' %}

{% block page-main %}
    <div class="article-detail">
        <h1>{{ article.title }}</h1>
        <p>{{ article.articledetail.content | safe }}</p>
    </div>
{% endblock %}

效果

BBS的个人主页,文章详情页以及模板继承,数据库关联查询操作
BBS的个人主页,文章详情页以及模板继承,数据库关联查询操作

github,点击跳转