展示所有文章
Django提供的分页功能说明
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'blog.settings.dev')
import django
django.setup()
# 这个时候才有django的环境 所以导入django中的模块必须写在这句话的后面才有效
from articles.models import Articles
# 正常的使用django的一些功能了
res = Articles.objects.all()
from django.core.paginator import Paginator
data = Paginator(res,2)
# print(data.count)
# 1. 先导入django的一个类
# from django.core.paginator import Paginator
# 2. 实例化这个类,这个类需要2个参数,第一个参数是利用模型得到的数据
# 第二个参数是每一页展示的数据量
# data = Paginator(res,2)
# 3. 这个类得到的结果,有几个方法和属性
# 属性相关
# count 属性 总共有多少条数据
# print(data.count)
# # num_pages 属性 总共有多少页数
# print(data.num_pages)
# # page_range 属性 页面的区间
# print(data.page_range)
# 方法
# get_page(页数) 方法
# page = data.get_page(1) # 结果就是第一页的数据内容
# has_next() 是否还有下一页
page = data.get_page(2)
print(page)
print(page.has_next()) # 是否还有下一页
print(page.has_previous()) # 是否还有上一页
print(page.next_page_number()) # 返回下一页的页数
print(page.previous_page_number()) # 返回上一页的页数
print(page.number) # 当前是多少页
# 没必要去死记
# 做开发 django
# 一些常用的 熟能生巧 自己清楚 cv工程师
# 复制粘贴 官方文档 复制粘贴 百度一下
改写展示所有文章的功能
在/apps/articles/views.py文件中,将原代码修改如下:
# blog/blog/apps/articles/views.py
from django.conf import settings
from django.db.models import Q
from django.core.paginator import Paginator
def index(request):
# 接收参数
search = request.GET.get('search')
order = request.GET.get('order')
# 用户的关键字查找出对应的数据内容
# 用户可能通过关键字来查找对应的数据内容 ==》有可能需要按照什么排序
# 有关键字 按照浏览量来查找
# 有关键字 按照创建时间来查找
# 没有关键字 按照浏览量来查找
# 没有关键字 按照创建时间来查找
if search:
# 按照浏览量来查找
if order=='read_num':
articles = Articles.objects.filter(Q(title__icontains=search)|Q(body__icontains=search)|Q(column__title__icontains=search)).order_by('-read_num')
# 按照创建时间来查找
else:
articles = Articles.objects.filter(Q(title__icontains=search)|Q(body__icontains=search)|Q(column__title__icontains=search))
else:
# 按照浏览量来查找
if order=='read_num':
articles = Articles.objects.all().order_by('-read_num')
else:
articles = Articles.objects.all()
# 做分页 导入django的分页类 开发项目的时候
paginator = Paginator(articles,settings.PAGE_NUM)
page = request.GET.get('page',1)
# 在html页面中 每次只展示一页的数据
articles = paginator.get_page(page)
return render(request,'articles/index.html',locals())
在/settings/dev.py文件中添加如下代码:
# 每页展示的数据条数
PAGE_NUM = 2
在templates/articles/index.html文件中,修改代码如下:
{% extends "base.html" %}
{% block title %} 博客正文 {% endblock title %}
{% block content %}
<div class="container">
<!--新增搜索栏-->
<div class="row">
<div class="col-auto mr-auto">
<form action="" class="form-inline">
<label class="sr-only">content</label>
<input type="text" class="form-control mb-2 mr-sm-2" name="search" placeholder="搜索文章">
</form>
</div>
</div>
<!--搜索提示信息-->
{% if search %}
{% if articles %}
<h4><span style="color: red">"{{ search }}"</span>的搜索结果如下</h4>
<hr>
{% else %}
<h4>暂无<span style="color: red">"{{ search }}"</span>有关的文章</h4>
{% endif %}
{% endif %}
<!--排序规则-->
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{% url 'articles:index' %}?search={{ search }}">最新</a>
</li>
<li class="breadcrumb-item">
<a href="{% url 'articles:index' %}?search={{ search }}&order=read_num">最热门</a>
</li>
</ol>
</nav>
<div class="col-12">
<div class="row mt-2">
{% for article in articles %}
<!-- 封面图-->
{% if article.avatar %}
<div class="col-3">
<img src="{{ article.avatar.url }}" alt="avatar" style="max-width: 100%;border-radius:20px ">
</div>
{% endif %}
<!-- 文章内容-->
<div class="col">
<!-- 文章栏目-->
<button type="button" class="btn btn-sm mb-2 btn-success">{{ article.column }}</button>
<!-- 文章标题-->
<h4>
<b>
<a href="{% url 'articles:detail' article.id %}">{{ article.title }}</a>
</b>
</h4>
<!-- 文章摘要-->
<div>
<p style="color: gray;">
{% if article.desc %}
{{ article.desc }}
{% else %}
还没有摘要
{% endif %}
</p>
</div>
<!-- 其他信息-->
<p>
<span style="color: green">
作者:{{ article.author }}
</span>
<span style="color: green">
浏览量:{{ article.read_num }}
</span>
<span style="color: green">
发布时间:{{ article.create_time|date:'Y-m-d' }}
</span>
<span style="color: green">
更新时间:{{ article.update_time|date:'Y-m-d' }}
</span>
</p>
</div>
<hr style="width: 100%;">
{% endfor %}
</div>
</div>
</div>
<!--页码导航-->
<div class="row pagination">
<div class="m-auto">
<span class="step-links">
<!--如果不是第一页,就显示上一页的按钮-->
{% if articles.has_previous %}
<a href="?page=1" class="btn btn-success">1</a>
<span>...</span>
<a href="?page={{ articles.previous_page_number }}" class="btn btn-success">{{ articles.previous_page_number }}</a>
{% endif %}
<!--当前页面-->
<span class="btn btn-danger btn-lg current">{{ articles.number }}</span>
<!--如果不是最后一页,就显示下一页的按钮-->
{% if articles.has_next %}
<a href="?page={{ articles.next_page_number }}" class="btn btn-success">{{ articles.next_page_number }}</a>
<span>...</span>
<a href="?page={{ articles.paginator.num_pages }}" class="btn btn-success">{{ articles.paginator.num_pages }}</a>
{% endif %}
</span>
</div>
</div>
{% endblock content %}
文章详情的优化
技术类的文章,使用markdown的语法写的,那展示的时候就不方便了,所以我们要优化展示markdown文章
在虚拟环境中下载第三方库:
pip install markdown
pip install Pygments
改写视图中的代码:
import markdown
# 查看文章详情
def detail(request,id):
# 根据文章的ID 查出对应的文章展示在html页面中
article = get_object_or_404(Articles, pk=id)
md = markdown.Markdown(extensions=[
# 包含 缩写 表格等常用的扩展
'markdown.extensions.extra',
# 语法高亮扩展
'markdown.extensions.codehilite',
# 允许自动生成目录
'markdown.extensions.toc'
])
body = md.convert(article.body)
# 没查看一次文章 就增加一次浏览量
article.read_num += 1
article.save()
# 取出上一篇文章和下一篇文章
pre_blog = Articles.objects.filter(create_time__gt=article.create_time).last()
next_blog = Articles.objects.filter(create_time__lt=article.create_time).first()
return render(request,'articles/detail.html',locals())
在static文件夹中创建一个md_css的文件夹,用来防止一些静态文件
进入md_css的路径在cmd中执行以下代码:
pygmentize -S monokai -f html -a .codehilite > monokai.css
在base.html中引入这个文件
<link rel="stylesheet" href="{% static 'md_css/monokai.css' %}">
在detail.html中,修改代码如下:
{% extends 'base.html' %}
{% block title %}文章详情{% endblock title %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-9">
<!--标题和作者-->
<h1 class="mt-4 mb-4">{{ article.title }}</h1>
<div class="alert alert-success">
作者:{{ article.author }}
创建时间:{{ article.create_time|date:'Y-m-d' }}
文章浏览量:{{ article.read_num }}
<!--如果当前登录的用户就是作者,则展示删除文章和修改文章-->
{% if request.user == article.author %}
<a href="#" onclick="confirm_delete()">删除文章</a>
<a href="{% url 'articles:update' article.id %}">修改文章</a>
{% endif %}
<!--文章的专栏-->
<button type="button" class="btn btn-success btn-sm mb-2">{{ article.column }}</button>
</div>
<!--文章的正文-->
<div class="col-12">
<p>{{ body|safe }}</p>
</div>
</div>
<!--目录-->
<div class="col-3 mt-4" id="sidebar" class="sidebar">
<div class="sidebar__inner">
<h4><strong>目录</strong> </h4>
<hr>
<div>
{{ md.toc|safe }}
</div>
<hr>
</div>
</div>
</div>
<div>
{% if pre_blog%}
<a href="{% url 'articles:detail' pre_blog.id %}">上一篇文章</a>
{% else %}
没有了
{% endif %}
{% if next_blog%}
<a href="{% url 'articles:detail' next_blog.id %}">下一篇文章</a>
{% else %}
没有了
{% endif %}
</div>
</div>
<!-- 粘性侧边栏样式 -->
<style>
.sidebar {
will-change: min-height;
}
.sidebar__inner {
transform: translate(0, 0); /* For browsers don't support translate3d. */
transform: translate3d(0, 0, 0);
will-change: position, transform;
}
</style>
<script>
//删除文章的函数
function confirm_delete(){
// 调用layer弹窗组件
layer.open({
title:"确认删除",
content:'确认删除这篇文章吗?',
yes:function (index,layero){
// 指定前往的url
location.href = '{% url "articles:delete" article.id %}'
},
})
}
</script>
{% endblock content %}