第四天:
1、个人页面分类信息展示:
把个人信息的分类信息提出来,套到模板中,在blog里面创建一个templatetags的文件夹把需要提出来的模板数据放到mytag.py里面
第一:通过当前登录用户查询到当前的所有文章数量按照文章title和num返回给前端; 第二:把所有标签分类的对象发送过去,前端通过模板语言tag.article_set.count获取数量; 第三:通过extra()查到想要获取的时间格式或者到年和月,拿到月份归档所在的所有文章信息;
from django import template from blog import models register = template.Library() @register.inclusion_tag("left_tag.html") def left_panel(username): user_obj = models.UserInfo.objects.filter(username=username).first() # 去数据库中根据用户名找所有的文章 blog = user_obj.blog # 查询左侧分类那些面板中用到的数据 # 1. 当前站点下的文章分类 # category_list = models.Category.objects.filter(blog=blog) from django.db.models import Count category_list = models.Category.objects.filter(blog=blog).annotate(num=Count("article")).values("title", "num") # 2. 文章标签分类 # 取到标签对象,拿到标签里面的数据,需要用到的是标题和标题数量 tag_list = models.Tag.objects.filter(blog=blog) # print(tag_list) # 3. 日期归档 # 查到日期和日期数 archive_list = models.Article.objects.filter(user=user_obj).extra( select={"ym": "DATE_FORMAT(create_time, '%%Y-%%m')"} ).values("ym").annotate(num=Count("nid")).values("ym", "num") # print(archive_list) return { "username": username, "category_list": category_list, "tag_list": tag_list, "archive_list": archive_list }
提出来的模板left_tag.html,里面url跳转按照归档名来跳转
<div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title">文章分类</h3> </div> <div class="panel-body"> <ul class="list-unstyled"> {% for category in category_list %} <li> <a href="/blog/{{ username }}/category/{{ category.title }}/">{{ category.title }}({{ category.num }})</a> </li> {% endfor %} </ul> </div> </div> <div class="panel panel-info"> <div class="panel-heading"> <h3 class="panel-title">文章标签</h3> </div> <div class="panel-body"> <ul class="list-unstyled"> {% for tag in tag_list %} <li> <a href="/blog/{{ username }}/tag/{{ tag.title }}/">{{ tag.title }}({{ tag.article_set.count }})</a> </li> {% endfor %} </ul> </div> </div> <div class="panel panel-warning"> <div class="panel-heading"> <h3 class="panel-title">日期归档</h3> </div> <div class="panel-body"> <ul class="list-unstyled"> {% for archive in archive_list %} <li> <a href="/blog/{{ username }}/archive/{{ archive.ym }}/">{{ archive.ym }}({{ archive.num }})</a> </li> {% endfor %} </ul> </div> </div>
在admin添加关联 Article2Tag
在home页面把左边的模板放在home页面里面:
blog>urls.py 里面的路由放根据 函数的home(request, username, *args) 正则写(.*)/(category|tag|avchier)/(.*)
为了可以让views.py里面可以选择当前点击的归档按照指定归档名路径访问
url(r'(.*)/(category|tag|archive)/(.*)/$', views.home), # home(request, username, tag, "跆拳"
home页面的views.py 里面的home函数,根据urls里面的正则取到正则和名字 来判断,按照文章分类、标签分类、日期归档查询各自的所有数据
def home(request, username, *args): """ :param request: 请求对象 :param username: 用户名 :return: """ # 去数据库根据用户名找到所有的文章 user_obj = models.UserInfo.objects.filter(username=username).first() print(user_obj) if not user_obj: return HttpResponse("404") else: # 拿到用户所有博客,为了拿到博客标题放在页面上头 blog = user_obj.blog if not args: # 查看当前用户的所有文章 data = models.Article.objects.filter(user__username=username) else: if args[0] == "category": # 按照文章分类查询 # 通过反向查询找到文章的名字的数据 data = models.Article.objects.filter(user=user_obj).filter(category__title=args[1]) # print(data) elif args[0] == 'tag': # 按照标签分类 data = models.Article.objects.filter(user=user_obj).filter(tags__title=args[1]) # print(data) else: # 按照日期归档查询 取到年、月 year, month = args[1].split("-") # print(year, month) data = models.Article.objects.filter(user=user_obj).filter(create_time__year=year, create_time__month=month) print(data) return render(request, 'home.html', { "username": username, "blog": blog, "article_list": data })
通过文章标题跳转到文章详情页面:
加上 | safe可以把需要的html格式都打印出来,不加的话不会打印
数据库中保存 富文本 内容时,保存的是完整的html代码。
{{content|safe}}
防止xss攻击
article.articledetail.content|safe
<div class="header"> <h3>{{ blog.title }}</h3> </div> <div class="container-fluid main"> <div class="row"> <div class="col-md-3"> {% load mytag %} {% left_panel username %} </div> <div class="col-md-9"> <!-- 文章详情 开始 --> <div class="article-detail"> <h1 class="article-title">{{ article.title }}</h1> <div class="article-content"> {{ article.articledetail.content|safe }} </div> </div> <!-- 文章详情 结束 --> </div> </div> </div>
views.py 根据article_id查出当前所有的文章详情
# 具体文章详细内容 def article_detail(request, username, article_id): user_obj = models.UserInfo.objects.filter(username=username).first() print(user_obj) # 去数据库中根据用户名找所有的文章 if not user_obj: return HttpResponse("404") else: blog = user_obj.blog ''' 文章详情视图函数 :param request: 请求对象 :param username: 用户名 :param article_id: 文章唯一id值 :return: ''' # 通过主键article_id拿到文章详细信息 article_obj = models.Article.objects.filter(pk=article_id).first() return render(request, 'article_detail.html', { "username": username, "blog": blog, "article": article_obj })
urls.py
url(r'(.*)/article/(\d+)/$', views.article_detail), # article_detail(request, username, article_id)
今日总结:
0. admin的简单使用 app/admin.py中按照格式注册我们的models 类 只有超级用户才能登录admin管理后台 1. 通过URL的巧妙设计实现视图函数的复用 2. 数据库中保存 富文本 内容时,保存的是完整的html代码。 {{content|safe}} 防止xss攻击 3. 自定义的inclusion_tag 1. app/templatetags --> (必须叫这个文件名 <python package>) 2. 在上面的目录下新建py文件 3. 在上面的py文件中: from django import template # 生成一个注册实例,必须叫register register = template.Library() @register.inclusion_tag("xx.html") def do_something(arg): ... return {k:v, ...} 4. 在html中先导入再使用(定义完上面的 要先重启Django项目再使用 ) 1. 导入 --> {% load 'py文件的名字' %} 2. 使用 --> {% 函数名 '参数' %}