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 %}