1.安装虚拟环境
pip install virtualenvwrapper
安装完之后设置一下环境变量WORK_HOME,设置自己想保存虚拟环境的的文件夹
常用命令
mkvirtualenv 虚拟环境名字 #创建虚拟环境
workon 虚拟环境名字 #打开摸个虚拟环境
deactivate #退出虚拟环境
lsvirtualenv #列出所有虚拟环境
rmvirtualenv 虚拟环境名字 #删除虚拟环境
workon 运行虚拟环境后
pip install django
安装django
2.Django的Hello world
首先先创建项目
django-admin startproject mysite
打开mysite文件
打开mysite文件夹
这些就是django项目目录
修改一些参数
打开mysite/mysite下的的settings.py
修改语言和时区
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'#UTC
新建views.py
写入以下代码
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello World!")
打开urls.py,添加以下代码
from . import views #这一行需要添加
urlpatterns = [
path('admin/', admin.site.urls),
path('',views.index),#这一行需要添加
]
python manage.py runserver
打开浏览器输入http://127.0.0.1:8000
可以看到如下界面
3.Django应用结构
创建一个app
python manage.py startapp article
文档结构如下
打开models.py,写入如下代码
# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=30)
content = models.TextField()
打开admin.py写入如下代码
from .models import Article
# Register your models here.
admin.site.register(Article)#注册模型
首先在settings.py把article app写入
然后制造迁移
python manage.py makemigrations
然后进行数据库迁移
python manage.py migrate
在进行上述步骤之前,你可能没有创建超级用户
超级用户的创建步骤如下
python manage.py migrate
python manage.py createsuperuser
输入管理员账号和密码(邮箱可以不填)
启动Django项目
python manage.py runserver
访问http://127.0.0.1:8000/admin
输入账号密码
可以看到如下界面
添加文章,点击article下的添加文章
可以多添加几篇,添加文章后界面如下
4.模板的使用
打开article下的的views.py
# Create your views here.
def article_detail(request,article_id):
return HttpResponse("文章id为:{}".format(article_id))
在urls.py下添加如下代码
from django.contrib import admin
from django.urls import path
from . import views
from article.views import article_detail#新添加
urlpatterns = [
path('admin/', admin.site.urls),
path('',views.index),
path('article/<int:article_id>',article_detail),#新添加
]
启动django网站
python manage.py runserver
访问如下地址
http://localhost:8000/article/1
(localhost等同于127.0.0.1)
效果如下图
打开article下的的views.py,修改代码如下
from django.shortcuts import render
from django.http import HttpResponse
from .models import Article
# Create your views here.
def article_detail(request,article_id):
article=Article.objects.get(id=article_id)
return HttpResponse("文章id为:{},标题{}".format(article_id,article.title))
结果如下图
再添加一个arcticle.content
可以再显示一个文章内容
当访问的页面不存在时,例如访问http://127.0.0.1:8000/article/5
网页会出现错误提示,说出现DoesNotExist错误,
首先可以使用try代码
try:
article=Article.objects.get(id=article_id)
except Article.DoesNotExist:
return HttpResponse("页面不存在!")
return HttpResponse("文章id为:{},标题:{},内容:{}".format(article_id,article.title,article.content))
也可以使用Http404
from django.http import HttpResponse,Http404
def article_detail(request,article_id):
try:
article=Article.objects.get(id=article_id)
except Article.DoesNotExist:
raise Http404("页面不存在!")
return HttpResponse("文章id为:{},标题:{},内容:{}".format(article_id,article.title,article.content))
创建模板显示内容
在arcticle app下创建templates文件夹
新建article_detail.html,然后在article app下的views.py写入如下代码
from django.shortcuts import render
from django.http import HttpResponse,Http404
from .models import Article
# Create your views here.
def article_detail(request,article_id):
try:
article=Article.objects.get(id=article_id)
content={}
content["article_obj"]=article
return render(request,"article_detail.html",content)
except Article.DoesNotExist:
raise Http404("页面不存在!")
在article_detail.html写入如下代码:
<!doctype html>
<html>
<head>
<charset="utf-8">
<title>文章内容</title>
</head>
<body>
<h2>{{ article_obj.title }}</h2>
<hr>
<p>{{ article_obj.content }}</p>
</body>
</html>
访问http://localhost:8000/article/1
也可以导入render_to_response
from django.shortcuts import render_to_response
return render_to_response("article_detail.html",content)
也是可以的
导入get_object_or_404(这个方法是比较简洁的)
from django.shortcuts import get_object_or_404
article=get_object_or_404(Article,pk=article_id)
content={}
content["article_obj"]=article
return render(request,"article_detail.html",content)
创建article_list.html,在article app下的views.py创建如下函数
def article_list(request):
article=Article.objects.all()
context={}
context["articles"]=article
return render(request,"article_list.html",context)
article_list.html里写入如下代码
<!doctype html>
<html>
<head>
<charset="utf-8">
<title>文章列表</title>
</head>
<body>
{% for article in articles %}
{#<a href="/article/{{article.pk}}">{{ article.title }}</a>#}
{#<br>#}
<a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a>
<br>
{% endfor %}
</body>
</html>
在mysite里面的urls.py下的path添加如下代码
path('article/',article_list,name="article_list"),
访问http://localhost:8000/article/
结果如下图
修改路由,在article下创建urls.py
将mysite下的ruls.py下的
path('article/<int:article_id>',article_detail,name="article_detail"),
path('article/',article_list,name="article_list"),
移动到article app下的urls.py
修改后代码如下
article下的urls.py
from django.urls import path
from .import views
urlpatterns = [
path('<int:article_id>',views.article_detail,name="article_detail"),
path('',views.article_list,name="article_list"),
]
mysite下的urls.py
from django.contrib import admin
from django.urls import path,include
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('',views.index),
path('article/',include("article.urls")),
]
仍然可以正常访问。
后台定制和修改模型
models.py
在article类下添加如下函数
def __str__(self):
return "Article:{}".format(self.title)
修改admin.py下的代码,注释掉
admin.site.register(Article)
添加如下代码
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display=("id","title","content")
ordering=("id",)#升序排列,倒叙加-,默认倒序
修改模型
修改模型要更新数据库
python manage.py makemigrations
python manage.py migrate
(需要设置默认值)
修改模型之前要先备份数据库文件
打开 article app下models.py
在Article类下添加如下代码
created_time=models.DateTimeField()
然后运行,python manage.py makemigrations
提示字段没有设置默认值,无法创建
(1)设置默认值
timezone.now
就可以了
python manage.py makemigrations
无报错
在article app下的admin.py下的list_display后面添加一个"created_time"字段
(2)
admin.py下修改如下代码
from django.utils import timezone
created_time=models.DateTimeField(default=timezone.now)
python manage.py makemigrations
(3)
created_time=models.DateTimeField(auto_now_add=True)#自动添加时间
选择1,输入
timezone.now
python manage.py migrate
创建成功
在article app下的admin.py下的list_display后面添加一个"created_time"字段
last_update_time=models.DateTimeField(auto_now=True)#增加最后修改时间
在article app下的admin.py下的list_display后面添加一个"last_update_time"字段
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
外键
from django.contrib.auth.models import User
auther=models.ForeignKey(User,on_delete=models.DO_NOTHING,default=1)
在article app下的admin.py下的list_display后面添加一个"auter"字段
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
修改字段名
author=models.ForeignKey(User,on_delete=models.DO_NOTHING,default=1)
在article app下的admin.py下的list_display后面添加一个"autor"字段
python manage.py makemigrations
Did you rename article.auther to article.author (a ForeignKey)? [y/N]y
python manage.py migrate
python manage.py runserver
is_deleted=models.BooleanField(default=False)#是否删除
readed_num=models.IntegerField(default=0)#阅读数量
在article app下的admin.py下的list_display后面添加两个"is_deleted,readed_num"字段
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
显示未被删除的数据
将第二篇文章的的is_deleted值改为True
在article app下的views.py的
article_list下的
article=Article.objects.all()
改为articles=Article.objects.filter(is_deleted=False)
构建个人博客网站
网站的功能模块
1.博客
博文
博客分类
博客标签
2.评论3.点赞
4.阅读
5.用户第三方登录
功能模块约等于Django App
mkvirtualenv mysite_env
pip install django
django-admin startproject mysite
python manage.py startapp blog
在blog app下的models.py写入如下代码
from django.contrib.auth.models import User
# Create your models here.
class BlogType(models.Model):
type_name=models.CharField(max_length=15)
class Blog(models.Model):
title=models.CharField(max_length=50)
blog_type=models.ForeignKey(BlogType,on_delete=models.DO_NOTHING)
content=models.TextField()
author=models.ForeignKey(User,on_delete=models.DO_NOTHING)
created_time=models.DateTimeField(auto_now_add=True)
last_update_time=models.DateTimeField(auto_now=True)
博文+博客分类
一篇博客一种分类√
一篇博客多种分类
在settings.py下添加blog app
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
修改blog app下admin.py文件的内容
from .models import Blog,BlogType
# Register your models here
@admin.register(BlogType)
class BlogTypeAdmin(admin.ModelAdmin):
list_display=("id","type_name",)
@admin.register(Blog)
class BlogAdmin(admin.ModelAdmin):
list_display=("title","blog_type","author","created_time","last_update_time")
访问http://localhost:8000/admin/
增加博客类型
Django 随笔 感悟
添加三篇博客
在blog app下models.py的BlogType类后面添加一个函数
def __str__(self):
return "BlogType:{}".format(self.type_name)
在blog app下models.py的Blog类后面添加一个函数
def __str__(self):
return "Blog:{}".format(self.title)
添加如下内容
第一篇博客
随笔
这是我的第一篇博客
pip freeze > requirements.txt
#导出需要的包
pip install -r requirements.txt
#安装需要的包
常用模版标签和过滤器
blog app下的views.py添加如下代码
from .models import Blog,BlogType
# Create your views here.
def blog_list(request):
context={}
context["blogs"]=Blog.objects.all()
return render_to_response('blog_list.html',context)
def blog_detail(request,blog_pk):
context={}
context["blog"]=get_object_or_404(Blog,pk=blog_pk)
return render_to_response("blog_detail.html",context)
在blog app文件夹内新建一个templates文件夹,添加
blog_list.html和blog_detail.html列表
blog_list.html内容如下
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>我的网站</title>
</head>
<body>
<div>
<h2>个人博客网站</h2>
</div>
{% for blog in blogs %}
<h3>{{ blog.title }}</h3>
<p>{{blog.content}}</p>
{% endfor %}
</body>
</html>
blog_detail.html内容如下
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ blog.title }}</title>
</head>
<body>
<h3>{{blog.title}}</h3>
<p>{{blog.content}}</p>
</body>
</html>
blog app文件夹下新建urls.py
from django.urls import path
from . import views
#start with blog
urlpatterns = [
#http://lcolhost:8000/blog/1
path('<int:blog_pk>',views.blog_detail,name="blog_detail"),
]
mysite下的urls.py添加如下代码
from django.urls import path,include
path('',blog_list,name="home"),
path('blog/',include("blog.urls")),
访问http://127.0.0.1:8000/
将blog_list.html的
{% for blog in blogs %}
<h3>{{ blog.title }}</h3>{#修改这一行#}
<p>{{blog.content}}</p>
{% endfor %}
改为下面的代码
<a href="{% url 'blog_detail' blog.pk %}">
{{ blog.title }}
</a>
在blog_detail.html下添加如下代码:
<div>
<a href="{% url 'home' %}">
<h2>个人博客网站</h2>
</a>
</div>
也可以将blog_list.html也改为以下代码
<div>
<a href="{% url 'home' %}">
<h2>个人博客网站</h2>
</a>
</div>
访问http://localhost:8000/admin/blog/blog/add/
添加一篇文章
标题:第二篇博客
类型:随笔
内容:这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客
这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客
访问http://127.0.0.1:8000/
统计博客数量
在blog_list.html下添加如下代码
<p>一共有{{ blog|length }}篇博客</p>
2.views.py下的blog_list函数下添加一行代码
context["blogs_count"]=Blog.objects.all().count()
在blog_list下添加如下代码
<p>一共有{{ blogs_count }}篇文章</p>
在blog_list下拓展for循环,在for循环内部添加如下带代码:
{% empty %}
<p>暂时没有博客</p>
{#如果为0篇文章则显示此内容#}
过滤器处理过长文本,在blog_list.html下的
<p>{{blog.content}}</p>
修改为:
<p>{{blog.content|truncatechars:30}}</p>
过长内容则显示为省略号
{{|truncatewords:30}}
用来统计英文单词,规则使用空格来辨认
blog_detail.html添加如下带代码:
<p>作者:{{ blog.author}}</p>
<p>发表日期:{{ blog.created_time|date:"Y-m-d h:n:s" }}</p>
<p>分类:{{ blog.blog_type }}</p>
{#时间默认十二进制的#}
{#把h改为G/H则为二十四进制#}
blog app下的views.py添加如下代码
def blogs_with_type(request,blog_type_pk):
context={}
blog_type=get_object_or_404(BlogType,pk=blog_type_pk)
context['blogs']=Blog.objects.filter(blog_type=blog_type)
context['blog_type']=blog_type
return render_to_response('blogs_with_type.html',context)
blog app下的urls.py添加如下代码
path('type/<int:blog_type_pk>',views.blogs_with_type,name="blogs_with_type"),
在templates文件夹下新建blogs_with_type.html,代码如下
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{blog_type.type_name}}</title>
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h2>个人博客网站</h2>
</a>
</div>
<h3>{{blog_type.type_name}}</h3>
{% for blog in blogs %}
<a href="{% url 'blog_detail' blog.pk %}">
{{ blog.title }}
</a>
<p>{{ blog.content|truncatechars:30 }}</p>
{% empty %}
<p>暂时没有博客</p>
{# 如果为0篇文章则显示此内容 #}
{% endfor %}
</body>
</html>
修改blog_detail.html文件夹下的<p>分类:{{ blog.blog_type }}</p>
为
<p>分类:
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}">
{{ blog.blog_type }}
</a>
</p>
配型为随笔的博客分类
再添加一篇django类型的博客
{#注释#}
truncatechars_html自动忽略掉html代码
truncatewords_html
是否信任html:safe
模板嵌套
循环 | for |
条件 | if,ifequeal,ifnotequal |
模板嵌套 | block,extends,include |
注释 | {# #} |
三个html文件有重复的地方
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h2>个人博客网站</h2>
</a>
</div>
</body>
</html>
blog app下的templates文件夹新建一个html文件,名为base.html内容如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<div>
<a href="{% url 'home' %}">
<h2>个人博客网站</h2>
</a>
</div>
<hr>
{% block content %}{% endblock %}
</body>
</html>
blog_detail.html文件修改为如下内容:
{% extends 'base.html' %}
{% block title %}
{{ blog.title }}
{% endblock %}
{% block content %}
<h3>{{blog.title}}</h3>
<p>作者:{{ blog.author}}</p>
<p>{{blog.content}}</p>
<p>发表日期:{{ blog.created_time|date:"Y-m-d h:n:s" }}</p>
<p>分类:
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}">
{{ blog.blog_type }}
</a>
</p>
{% endblock %}
blog_list.html内容修改为:
{% extends 'base.html' %}
{#页面标题#}
{% block title %}
我的网站
{% endblock %}
{#页面内容#}
{% block content %}
{% for blog in blogs %}
<a href="{% url 'blog_detail' blog.pk %}">
{{ blog.title }}
</a>
<p>{{ blog.content|truncatechars:30 }}</p>
{% empty %}
<p>暂时没有博客</p>
{# 如果为0篇文章则显示此内容 #}
{% endfor %}
<p>一共有{{ blogs_count }}篇文章</p>
{% endblock %}
blogs_with_type.html修改为如下内容:
{% extends 'base.html' %}
{#页面标题#}
{% block title %}
{{blog_type.type_name}}
{% endblock %}
{#页面内容#}
{% block content %}
<h3>{{blog_type.type_name}}</h3>
{% for blog in blogs %}
<a href="{% url 'blog_detail' blog.pk %}">
{{ blog.title }}
</a>
<p>{{ blog.content|truncatechars:30 }}</p>
{% empty %}
<p>暂时没有博客</p>
{# 如果为0篇文章则显示此内容 #}
{% endfor %}
{% endblock %}
python manage.py runserver
访问http://127.0.0.1:8000 可以正常访问
全局模板文件夹设置
在项目的根目录下,新建templates文件夹
打开settings.py文件
TEMPLATES下修改'DIRS': []为:
'DIRS': [
os.path.join(BASE_DIR,'templates'),
],
把base.html移动到全局的templates文件夹下
访问http://lcoalhost:8000 如下图
模板文件设置建议
想任意迁移app,templates建议放在app文件夹里面
app为项目工作,可以放在全局的templates文件夹下,一般在templates文件夹下新建文件夹名字命名为app的名字即可
修改blog app下views.py的模板引用
访问http://lcoalhost:8000 网站还在正常运行
CSS页面设计
导航栏
logo网站名称+导航
把base.html文件添加两个a标签,代码如下:
<a href="/">首页</a>
<a href="{% url 'blog_list' %}">博客列表</a>
blog app下的urls.py添加一个路由
path('',views.blog_list,name='blog_list'),
修改首页的处理方法
新建文件命名为views.py保存到mysite文件夹下,
输入以下代码:
from django.shortcuts import render_to_response
def home(request):
context={}
return render_to_response('home.html',context)
mysite文件夹下修改urls.py
from .views import home
path('',home,name="home"),
在全局的templates文件夹下新建home.html
输入一下内容:
{% extends 'base.html' %}
{# 标题 #}
{% block title %}
我的网站|首页
{% endblock %}
{#主体内容#}
{% block content %}
<h3>欢迎访问我的网站,随便看</h3>
{% endblock %}
访问:http://127.0.0.1:8000/
页面美化:CSS
把base.html添加css代码,总体代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<div class="nav">
<a class="logo" href="{% url 'home' %}">
<h2>个人博客网站</h2>
</a>
<a href="/">首页</a>
<a href="{% url 'blog_list' %}">博客列表</a>
</div>
{% block content %}{% endblock %}
<style type="text/css">
*{
margin: 0px;
padding: 0px;
}
div.nav{
background-color: #eee;
border-bottom: 1px solid #ccc;
padding:10px 5px;
}
div.nav a.logo {
display:inline-block;
font-size: 120%;
}
div.nav a{
text-decoration: none;
color:black;
padding:5px 10px;
}
</style>
</body>
</html>
home.html添加如下代码:
<h3 class="home-content">欢迎访问我的网站,随便看</h3>
<style type="text/css">
.home-content{
font-size:222%;
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
}
</style>
效果如下图
引用静态文件
静态文件
css文件
js文件
图片等
新建文件夹名为static,在static文件夹下新建base.css,把base.html里面的css代码粘贴到base.css里面。
在settings.py最后添加如下代码:
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static'),
]
在base.html的head里面添加如下代码:
<link rel="stylesheet" href="/static/base.css">
第二种方法加载静态文件
在base.html文件下添加如下代码
{% load staticfiles %}
<link rel="stylesheet" href="{% static 'base.css' %}">
刷新网页,网页没有变化
同理在static文件夹下新建home.css,把home.html文件下的css代码剪切过去,在base.html文件夹下添加一行代码。
{% block header_extends %}{% endblock %}
在home.html文件里面添加一行代码:
{% load staticfiles %}
{% block header_extends %}
<link rel="stylesheet" href="{% static 'home.css' %}">
{% endblock %}
主题内容
尾注
css框架协助前端布局
下载bootstrap3,官网
在static文件夹下新建bootstrap文件夹,放入下载的css、js文件
打开base.html,添加对bootstrap的css和js的引用,
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
<script type="text/javascript" src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
下载最新版的jquery官网,放到static文件夹下
添加对jquery的引用,jquery的引用要放在bootstrap.js的前面
<script type="text/javascript" src="{% static 'jquery-3.3.1.min.js' %}"></script>
<!--要相兼容IE请下载jquery1的版本-->
结构如下图:
,在head标签里面添加一个meta标签
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
添加导航栏,在base.html文件夹下添加如下代码:
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="{% url 'home' %}">
个人博客网站
</a>
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="collapse navbar-collapse" id="navbar-collapse">
<ul class="nav navbar-nav">
<li class="{% block nav_home_active %}{% endblock %}">
<a href="{% url 'home' %}">首页</a>
</li>
<li class="{% block nav_blog_active %}{% endblock %}">
<a href="{% url 'blog_list' %}">博客</a>
</li>
</ul>
</div>
</div>
</div>
把对base.css的引用代码修改如下,多余的删除
*{
margin: 0px;
padding: 0px;
}
body{
margin-top: 70px !important;
}
在home.html文件夹下添加如下代码:
{% block nav_home_active %}
active
{% endblock %}
blog_list.html,blog_detail.html和blog_with_type.html文件都添加如下代码:
{% block nav_blog_active %}active{% endblock %}
结果如下:
bootstrap响应式布局
修改blog_list.html文件,修改后代码如下
{% extends 'base.html' %}
{#页面标题#}
{% block title %}
我的网站
{% endblock %}
{# 加载静态文件 #}
{% load staticfiles %}
{# 文件引用 #}
{% block header_extends %}
<link rel="stylesheet" href="{% static 'blog/blog.css' %}">
{% endblock %}
{% block nav_blog_active %}active{% endblock %}
{#页面内容#}
{% block content %}
<div class="container">
<div class="row">
<div class="col-sm-8 col-md-9 col-lg-10">
<div class="panel panel-default">
<div class="panel-heading">
{# 博客列表 (一共有{{ blogs_count }}篇文章)#}
{% block blog_list_title %}
博客列表 (一共有{{ blogs_count }}篇文章)
{% endblock %}
</div>
<div class="panel-body">
{% for blog in blogs %}
<div class="blog">
<h3>
<a href="{% url 'blog_detail' blog.pk %}">
{{ blog.title}}
</a>
</h3>
<p class="blog-info">
<span class="glyphicon glyphicon-tag"></span>
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}">{{ blog.blog_type }}</a>
<span class="glyphicon glyphicon-time"></span>
{{ blog.created_time|date:'Y-m-d' }}
</p>
<p>{{ blog.content|truncatechars:50 }}</p>
</div>
{% empty %}{# 如果为0篇文章则显示此内容 #}
<div class="blog">
<h3>暂时没有博客</h3>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="hidden-xs col-sm-4 col-md-3 col-lg-2">
<div class="panel panel-default">
<div class="panel-heading">博客分类</div>
<div class="panel-body">
<ul class="blog-types">
{% for blog_type in blog_types %}
<li>
<a href="{% url 'blogs_with_type' blog_type.pk %}">{{ blog_type.type_name }}</a>
</li>
{% empty %}
<li>暂无分类</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
修改blog app下的blog_list函数,添加代码如下
context["blog_types"]=BlogType.objects.all()
把全局templates文件夹下的blog文件夹剪切粘贴到blog app下的templates文件夹下
在static文件夹下新建blog.css
写入如下代码:
.blog-types{
list-style-type: none;
}
div.blog:not(:last-child){
margin-bottom: 2em;
padding-bottom: 1em;
border-bottom: 1px solid #ddd;
}
div.blog h3{
margin-top: 0.5em;
}
div.blog p.blog-info{
margin-bottom: 0;
}
ul.blog-info-description{
list-style-type: none;
margin-bottom: 1em;
}
ul.blog-info-description li{
display: inline-block;
margin-right: 2em;
}
div.blog-content{
text-indent: 2em;
}
blog app下创建static文件夹,在static文件夹下新建blog文件夹,把blog.css移动到blog app下的static文件夹下的blog文件夹
修改blogs_with_type.html代码
{% extends 'blog/blog_list.html' %}
{#页面标题#}
{% block title %}
{{blog_type.type_name}}
{% endblock %}
{% block blog_list_title %}
{{blog_type.type_name}}:
一共有{{ blogs_count }}篇文章
<a href="{% url 'blog_list' %}">返回博客列表</a>
{% endblock %}
修改views.py下的blogs_with_type函数代码
context['blogs_count'] = Blog.objects.filter(blog_type=blog_type).count()
context["blog_types"]=BlogType.objects.all()
修改blog_detail.html代码如下:
{% extends 'base.html' %}
{# title #}
{% block title %}
{{ blog.title }}
{% endblock %}
{# nav #}
{% block nav_blog_active %}active{% endblock %}
{# 引用 #}
{% load staticfiles %}
{% block header_extends %}
<link rel="stylesheet" href="{% static 'blog/blog.css' %}">
{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<h3>{{blog.title}}</h3>
<ul class="blog-info-description">
<li>作者:{{ blog.author}}</li>
<li>分类:
<a href="{% url 'blogs_with_type' blog.blog_type.pk %}">
{{ blog.blog_type }}
</a>
</li>
<li>发表日期:{{ blog.created_time|date:"Y-m-d h:n:s" }}</li>
</ul>
<div class="blog-content"> {{blog.content}}</div>
</div>
</div>
</div>
{% endblock %}
最终效果入下:
分页和shell命令行模式
新增或编辑博客内容
博客文章数量较多导致加载过慢,分页加载
shell命令行模式添加博客
1、cmd python manage.py shell
#添加一篇文章
from blog.models import Blog
dir()
# ['Blog', '__builtins__']
Blog.objects.all()
# <QuerySet [<Blog: Blog:第一篇博客>, <Blog: Blog:第二篇博客>, <Blog: Blog:第三篇博客>]>
Blog.objects.count()
# 3
Blog.objects.all().count()
# 3
blog=Blog()
dir()
# ['Blog', '__builtins__', 'blog']
Blog.objects.all()
# <QuerySet [<Blog: Blog:第一篇博客>, <Blog: Blog:第二篇博客>, <Blog: Blog:第三篇博客>]>
blog.title="shell下的第一篇博客"
blog.content="shell下的博客内容"
from blog.models import BlogType
BlogType.objects.all()
# <QuerySet [<BlogType: Django>, <BlogType: 随笔>, <BlogType: 感悟>]>
BlogType.objects.all()[0]
# <BlogType: Django>
blog_type=BlogType.objects.all()[0]
blog.blog_type=blog_type
from django.contrib.auth.models import User
User.objects.all()
# <QuerySet [<User: wjl>]>
user=User.objects.all()[0]
blog.author=user
blog.save()
Blog.objects.all()
# <QuerySet [<Blog: Blog:第一篇博客>, <Blog: Blog:第二篇博客>, <Blog: Blog:第三篇博客>, <Blog: B
log:shell下的第一篇博客>]>
访问localhost:8000/admin
dir(blog)
#查看blog的方法
# ['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__', '__dict__', '__dir__',
# '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '_
#_hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new_
#_', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '_
#_str__', '__subclasshook__', '__weakref__', '_check_column_name_clashes', '_check_field_name_c
#lashes', '_check_fields', '_check_id_field', '_check_index_together', '_check_indexes', '_chec
#k_local_fields', '_check_long_column_names', '_check_m2m_through_same_relationship', '_check_m
#anagers', '_check_model', '_check_model_name_db_lookup_clashes', '_check_ordering', '_check_pr
#operty_name_related_field_accessor_clashes', '_check_single_primary_key', '_check_swappable',
#'_check_unique_together', '_do_insert', '_do_update', '_get_FIELD_display', '_get_next_or_prev
#ious_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_get_unique_checks', '_meta'
#, '_perform_date_checks', '_perform_unique_checks', '_save_parents', '_save_table', '_set_pk_v
#al', '_state', 'author', 'author_id', 'blog_type', 'blog_type_id', 'check', 'clean', 'clean_fi
#elds', 'content', 'created_time', 'date_error_message', 'delete', 'from_db', 'full_clean', 'ge
#t_deferred_fields', 'get_next_by_created_time', 'get_next_by_last_update_time', 'get_previous_
#by_created_time', 'get_previous_by_last_update_time', 'id', 'last_update_time', 'objects', 'pk
#', 'prepare_database_save', 'refresh_from_db', 'save', 'save_base', 'serializable_value', 'tit
#le', 'unique_error_message', 'validate_unique']
blog.last_update_time
# datetime.datetime(2019, 2, 8, 8, 3, 47, 270708, tzinfo=<UTC>)
2、for循环执行新增博客代码
from blog.models import Blog,BlogType
from django.contrib.auth.models import User
user=User.objects.all()[0]
blog_type=BlogType.objects.all()[0]
for i in range(1,31):
blog=Blog()
blog.title="for %s" % i
blog.content="for循环第%s篇文章" % i
blog.blog_type=blog_type
blog.author=user
blog.save()
Blog.objects.all().count()
# 34
分页
from django.core.paginator import Paginator
dir()
# ['Blog', 'BlogType', 'Paginator', 'User', '__builtins__', 'blog', 'blog_type', 'i', 'user']
del Blog
dir()
# ['BlogType', 'Paginator', 'User', '__builtins__', 'blog', 'blog_type', 'i', 'user']
exit()
分页器:
from django.core.paginator import Paginator
paginator=Paginator(object_list,each_page_count)
page1=paginator.page(1)
python manage.py shell
from django.core.paginator import Paginator
from blog.models import Blog
blogs=Blog.objects.all()
blogs.count()
#34
paginator=Paginator(blogs,10)
# <string>:1: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <class 'blog.models.Blog'> QuerySet.
# <string>:1:无序对象列表警告:分页可能会产生与无序object_list不一致的结果:<class'blog.models.Blog'> QuerySet。
"""
在blog app下的models.py下的Blog添加如下代码:
制造迁移
python manage.py makemigrations
同步数据库
python manage.py migrate
重新开启本地服务
"""
exit()
python manage.py shell
from django.core.paginator import Paginator
from blog.models import Blog
blogs=Blog.objects.all()
paginator=Paginator(blogs,10)
paginator
#<django.core.paginator.Paginator object at 0x0000000003D85B70>
dir(paginator)
#['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__
#', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt_
#_', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__
#', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_check_object_list_is_ordered'
#, '_get_page', 'allow_empty_first_page', 'count', 'get_page', 'num_pages', 'object_list', 'orp
#hans', 'page', 'page_range', 'per_page', 'validate_number']
paginator.count
# 34
paginator.num_pages
# 4
paginator.page_range
# range(1, 5)
page1=paginator.page(1)
page1
#<Page 1 of 4>
dir(page1)
#['__abstractmethods__', '__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__
#doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash
#__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__module__',
# '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__'
#, '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_abc_cache', '_abc
#_negative_cache', '_abc_negative_cache_version', '_abc_registry', 'count', 'end_index', 'has_n
#ext', 'has_other_pages', 'has_previous', 'index', 'next_page_number', 'number', 'object_list',
# 'paginator', 'previous_page_number', 'start_index']
help(page1.count)
"""
Help on method count in module collections.abc:
count(value) method of django.core.paginator.Page instance
S.count(value) -> integer -- return number of occurrences of value
"""
page1.object_list
"""
<QuerySet [<Blog: Blog:for 30>, <Blog: Blog:for 29>, <Blog: Blog:for 28>, <Blog: Blog:for 27>,
<Blog: Blog:for 26>, <Blog: Blog:for 25>, <Blog: Blog:for 24>, <Blog: Blog:for 23>, <Blog: Bl
og:for 22>, <Blog: Blog:for 21>]>
"""
page1.object_list.count()
# 10
"""
前端:发送请求,请求打开具体的分页内容
后端:处理请求,返回具体分页内容
例如:localhost:8000/blog/page/1
或者:localhost:8000/blog?page=1
第二个是get请求
"""
编写后端处理方法
blog app下的views.py的blog_list函数下添加如下代码:
def blog_list(request):
blogs_all_list=Blog.objects.all()
paginator=Paginator(blogs_all_list,10) #每十页进行分页
page_num = request.GET.get('page',1) #字典,如果没有默认给1,获取页码参数
page_of_blogs=paginator.get_page(page_num)
#得到无效字符,自动返回1
context={}
#context["blogs"]=page_of_blogs.object_list
context['page_of_blogs']=page_of_blogs
context["blogs_count"]=Blog.objects.all().count()
context["blog_types"]=BlogType.objects.all()
return render_to_response('blog/blog_list.html',context)
修改blog_list.html下的代码:
把<div class="panel-body">下的
{% for blog in blogs %}```` 改为
{% for blog in page_of_blogs.object_list %}````
在<div class="col-sm-8 col-md-9 col-lg-10">新建div,添加如下代码:
<div>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if page_of_blogs.has_previous %}
<li>
<a href="?page={{ page_of_blogs.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
{% endif %}
{% for page_num in page_of_blogs.paginator.page_range %}
<li><a href="?page={{ page_num }}">{{ page_num }}</a></li>
{% endfor %}
{% if page_of_blogs.has_next %}
<li>
<a href="?page={{ page_of_blogs.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% else %}
{% endif %}
</ul>
</nav>
</div>
优化分页展示
页码很多怎么显示
blog app views.py下的blog_list函数代码
paginator=Paginator(blogs_all_list,10) #每十篇进行分页
修改为
paginator=Paginator(blogs_all_list,2) #每2篇进行分页
优化:
当前页高亮
不要过多页码选择,凸显页面布局
修改blog_list.html
在{# 全部页码 #}下修改为如下代码:
{% for page_num in page_of_blogs.paginator.page_range %}
{% if page_num == page_of_blogs.number %}
<li class="active">
<span>{{ page_num }}</span>
</li>
{% else %}
<li>
<a href="?page={{ page_num }}">{{ page_num }}</a>
</li>
{% endif %}
{% endfor %}
blog app下views.py修改blog_list函数代码
currentr_page_num=page_of_blogs.number #获取当前页码
page_range=[currentr_page_num-2,currentr_page_num-1,currentr_page_num,currentr_page_num+1,currentr_page_num+2]
context['page_range']=page_range
修改blog_list.html
在{# 全部页码 #}下修改为如下代码:
{% for page_num in page_range %}
blog app下views.py修改blog_list函数代码
page_range=list(range(max(currentr_page_num-2,1),currentr_page_num))+list(range(currentr_page_num,min(currentr_page_num+2,paginator.num_pages)+1))
在blog app下的views.py下的blog_list函数下添加如下代码:
#加上省略页码标记
if page_range[0]-1 >=2:#3-1>=2 第5页开始
page_range.insert(0,'...')
if paginator.num_pages-page_range[-1]>=2:
page_range.append("...")#15<=17-2
在blog app下的views.py下的blog_list函数下添加如下代码:
if page_range[0]!=1:
page_range.insert(0,1)
if page_range[-1]!=paginator.num_pages:
page_range.append(paginator.num_pages)
修改blog_list.html文件下的{#全部代码#}下的{% else %}代码
{% if page_num == '...' %}
<li><span>{{ page_num }}</span></li>
{% else %}
<li><a href="?page={{ page_num }}">{{ page_num }}</a></li>
{% endif %}
找到blog_list.html里面的一共有多少篇博客的代码,剪切粘贴至</nav>前面的新建的<p></p>标签里面
代码如下:
共有{{ page_of_blogs.paginator.count }}篇文章,共{{ page_of_blogs.paginator.num_pages }}页,当前第{{ page_of_blogs.number }}页
为<ul class="pagination">上的nav/div添加一个class为mypaginator,修改blog.css
添加如下代码:
nav.mypaginator{
text-align: center;
}
在blog app下的views.py下的blogs_with_type函数删除原本代码,添加如下代码:
context={}
blog_type=get_object_or_404(BlogType,pk=blog_type_pk)
blogs_all_list = Blog.objects.filter(blog_type=blog_type)
paginator = Paginator(blogs_all_list, 2) # 每十篇进行分页
page_num = request.GET.get('page', 1) # 字典,如果没有默认给1,获取页码参数
page_of_blogs = paginator.get_page(page_num) # 得到无效字符,自动返回1
currentr_page_num = page_of_blogs.number # 获取当前页码
page_range = list(range(max(currentr_page_num - 2, 1), currentr_page_num)) + \
list(range(currentr_page_num, min(currentr_page_num + 2, paginator.num_pages) + 1))
# 获取当前页码以及前后各两页的页码范围
# 加上省略页码标记
if page_range[0] - 1 >= 2: # 3-1>=2 第5页开始
page_range.insert(0, '...')
if paginator.num_pages - page_range[-1] >= 2:
page_range.append("...") # 15<=17-2
# 加上首页和尾页
if page_range[0] != 1:
page_range.insert(0, 1)
if page_range[-1] != paginator.num_pages:
page_range.append(paginator.num_pages)
context['blog_type'] = blog_type
context["blogs"]=page_of_blogs.object_list
context['page_of_blogs'] = page_of_blogs
context["blog_types"] = BlogType.objects.all()
context['page_range'] = page_range
return render_to_response('blog/blogs_with_type.html',context)
blog app下的views.py下定义全局变量
each_page_blogs_number=2
#paginator=Paginator(blogs_all_list,2),2改为each_page_blogs_number
公用全局设置可以放在settings统一管理,在settings.py下添加自定义参数EACH_PAGE_BLOGS_NUMBER=7
blog app下的views.py下添加如下代码:
from django.conf import settings
#paginator=Paginator(blogs_all_list,2),2改为settings.EACH_PAGE_BLOGS_NUMBER
注释掉blog_with_type.html的代码
{# 一共有{{ page_of_blogs.paginator.count }}篇文章#}
上下篇博客和按月分类
filter筛选条件:
名称 | 表示 |
---|---|
直接筛选 | = |
大于 | __gt(greater than) |
大于等于 | __gte |
小于 | __lt(less than) |
小于等于 | __lte |
包含 | __contains(加i忽略大小写) |
开头是 | __startwith |
结尾是 | __endwith |
其中之一 | __in |
范围 | __range |
在blog app下的views.py里面的blog_detail函数添加如下代码:
context["previous_blog"]=Blog.objects.filter(created_time__gt=blog.created_time).last()#[-1]
context["next_blog"]=Blog.objects.filter(created_time__lt=blog.created_time).first()#[0]
打开blog_detail.html
在<div class="blog-content"> {{blog.content}}</div>
后面添加如下代码:
<div class="blog-more">
<p>
{% if previous_blog %}
<a href="{% url 'blog_detail' previous_blog.pk %}">上一篇:{{ previous_blog.title }} </a>
{% else %}
木有了
{% endif %}
</p>
<p>
{% if next_blog %}
<a href="{% url 'blog_detail' next_blog.pk %}">下一篇:{{ next_blog.title }}</a>
{% else %}
木有了
{% endif %}
</p>
</div>
blog.css添加如下代码:
div.blog-more{
margin-top: 1em;
}
开启shell模式
python manage.py shell
from blog.models import Blog
Blog.objects.filter(title__contains="for")
Blog.objects.filter(title__icontains="for")
# SQLite不支持
Blog.objects.filter(id__in=[1,3,4])
Blog.objects.filter(id__range=(1,4))
exclude排除条件
用法和filter一样,都是得到查询QuerySet,相当于filter条件的取反
Blog.objects.exclude(pk=3)
Blog.objects.exclude(pk<=3)
条件中的双下划线:
- 字段查询类型
- 外键拓展
- 日期拓展
- 支持链式查询
Blog.objects.exclude(created_time__year=2019)# month
按日期分类
在blog app下的views.py添加如下代码:
def blogs_with_date(request,year,month):
blogs_all_list = Blog.objects.filter(created_time__year=year,created_time__month=month)
paginator = Paginator(blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER) # 每十篇进行分页
page_num = request.GET.get('page', 1) # 字典,如果没有默认给1,获取页码参数
page_of_blogs = paginator.get_page(page_num) # 得到无效字符,自动返回1
currentr_page_num = page_of_blogs.number # 获取当前页码
page_range = list(range(max(currentr_page_num - 2, 1), currentr_page_num)) + \
list(range(currentr_page_num, min(currentr_page_num + 2, paginator.num_pages) + 1))
# 获取当前页码以及前后各两页的页码范围
# 加上省略页码标记
if page_range[0] - 1 >= 2: # 3-1>=2 第5页开始
page_range.insert(0, '...')
if paginator.num_pages - page_range[-1] >= 2:
page_range.append("...") # 15<=17-2
# 加上首页和尾页
if page_range[0] != 1:
page_range.insert(0, 1)
if page_range[-1] != paginator.num_pages:
page_range.append(paginator.num_pages)
#context['blog_type'] = blog_type
context = {}
context["blogs_with_date"]="%s年%s月" % (year,month)
context["blogs"] = page_of_blogs.object_list
context['page_of_blogs'] = page_of_blogs
context["blog_types"] = BlogType.objects.all()
context['page_range'] = page_range
context["blog_dates"] = Blog.objects.dates('created_time', 'month', order="DESC")
return render_to_response('blog/blogs_with_date.html',context)
在blog app下的urls.py添加如下代码:
path('date/<int:year>/<int:month>',views.blogs_with_date,name="blogs_with_date")
打开blog_list.html文件,在<div class="panel panel-default">同级的建立一个<div class="panel panel-default"></div>
里面添加如下代码:
<div class="panel panel-default">
<div class="panel-heading">
日期归档
</div>
<div class="panel-body">
<ul>
{% for blog_date in blog_dates %}
<li>{{ blog_date|date:"Y年-m月" }}</li>
{% endfor %}
</ul>
</div>
</div>
在blog app下的views.py的blog_list函数添加如下代码:
context["blog_dates"]=Blog.objects.dates('created_time','month',order="DESC")# field ['year','month','day'] ['ASC','DESC']
修改base.css添加如下代码:
ul{
list-style: none;
/*去掉li的圆点*/
}
新建blogs_with_date.html
里面添加如下内容:
{% extends 'blog/blog_list.html' %}
{% block title %}
{{blog_type.type_name}}
{% endblock %}
{% block blog_list_title %}
日期归档:{{blogs_with_date}}:
<a href="{% url 'blog_list' %}">返回博客列表</a>
{% endblock %}
整理重复代码
blog app下views.py的代码整理如下:
from django.shortcuts import render_to_response,get_object_or_404
from .models import Blog,BlogType
from django.core.paginator import Paginator
from django.conf import settings
# Create your views here.
def get_blog_list_common_data(request,blogs_all_list):
paginator = Paginator(blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER) # 每十篇进行分页
page_num = request.GET.get('page', 1) # 字典,如果没有默认给1,获取页码参数
page_of_blogs = paginator.get_page(page_num) # 得到无效字符,自动返回1
currentr_page_num = page_of_blogs.number # 获取当前页码
page_range = list(range(max(currentr_page_num - 2, 1), currentr_page_num)) + \
list(range(currentr_page_num, min(currentr_page_num + 2, paginator.num_pages) + 1))
# 获取当前页码以及前后各两页的页码范围
# 加上省略页码标记
if page_range[0] - 1 >= 2: # 3-1>=2 第5页开始
page_range.insert(0, '...')
if paginator.num_pages - page_range[-1] >= 2:
page_range.append("...") # 15<=17-2
# 加上首页和尾页
if page_range[0] != 1:
page_range.insert(0, 1)
if page_range[-1] != paginator.num_pages:
page_range.append(paginator.num_pages)
context = {}
# context["blogs"]=page_of_blogs.object_list
context['page_of_blogs'] = page_of_blogs
context["blogs_count"] = Blog.objects.all().count()
context["blog_types"] = BlogType.objects.all()
context['page_range'] = page_range
context["blog_dates"] = Blog.objects.dates('created_time', 'month', order="DESC")
return context
def blog_list(request):
blogs_all_list=Blog.objects.all()
context=get_blog_list_common_data(request,blogs_all_list)
return render_to_response('blog/blog_list.html',context)
def blogs_with_type(request,blog_type_pk):
blog_type=get_object_or_404(BlogType,pk=blog_type_pk)
blogs_all_list = Blog.objects.filter(blog_type=blog_type)
context = get_blog_list_common_data(request, blogs_all_list)
context['blog_type'] = blog_type
return render_to_response('blog/blogs_with_type.html',context)
def blogs_with_date(request,year,month):
blogs_all_list = Blog.objects.filter(created_time__year=year,created_time__month=month)
context = get_blog_list_common_data(request, blogs_all_list)
context["blogs_with_date"]="%s年%s月" % (year,month)
return render_to_response('blog/blogs_with_date.html',context)
def blog_detail(request,blog_pk):
context={}
blog=get_object_or_404(Blog,pk=blog_pk)
context["previous_blog"]=Blog.objects.filter(created_time__gt=blog.created_time).last()
context["next_blog"]=Blog.objects.filter(created_time__lt=blog.created_time).first()#[0]
context["blog"]=blog
#Blog.objects.all(pk=blog_pk)
return render_to_response("blog/blog_detail.html",context)
博客分类统计
在blog app下的views.py的get_blog_list_common_data函数添加如下代码
#获取博客分类的对应博客数量
blog_types=BlogType.objects.all()
blog_types_list=[]
for blog_type in blog_types:
blog_type.blog_count=Blog.objects.filter(blog_type=blog_type).count()
blog_types_list.append(blog_type)
context["blog_types"] = blog_types_list
在博客分类下找到{{ blog_type.type_name }}在他的后面追加一下代码:
({{ blog_type.blog_count }})
刷新页面查看:
annotate拓展查询字段
(1)blog app下的models.py的Blog类修改一行代码为:
blog_type=models.ForeignKey(BlogType,on_delete=models.DO_NOTHING,related_name="blog_blog")
注释掉刚刚添加的代码,添加如下代码:
from django.db.models import Count
BlogType.objects.annotate(Count('blog_blog'))
(2)注释掉刚刚添加的代码,添加如下代码:
from django.db.models import Count
BlogType.objects.annotate(blog_count=Count('blog'))
获取日期归档对应的博客数量
在blog app下的views.py的get_blog_list_common_data函数添加如下代码
#获取日期归档对应的博客数量
blog_dates=Blog.objects.dates('created_time', 'month', order="DESC")
blog_dates_dict={}
for blog_date in blog_dates:
blog_count=Blog.objects.filter(created_time__year=blog_date.year,created_time__month=blog_date.month).count()
blog_dates_dict[blog_date]=blog_count
context["blog_dates"] = blog_dates_dict
在日期归档下找到<div class="panel-body">在他的<ul></ul>里面追加一下代码:
{% for blog_date,blog_count in blog_dates.items %}
<li>
<a href="{% url 'blogs_with_date' blog_date.year blog_date.month %}">
{{ blog_date|date:"Y年-m月" }}({{ blog_count }})
</a>
</li>
{% endfor %}
刷新页面查看:
网友评论