Django2.0学习笔记1(哔哩哔哩杨士航)

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文件
Django2.0学习笔记1(哔哩哔哩杨士航)_第1张图片

打开mysite文件夹
Django2.0学习笔记1(哔哩哔哩杨士航)_第2张图片

这些就是django项目目录

修改一些参数

打开mysite/mysite下的的settings.py
修改语言和时区

LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'#UTC

新建views.py
Django2.0学习笔记1(哔哩哔哩杨士航)_第3张图片

写入以下代码

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
可以看到如下界面

Django2.0学习笔记1(哔哩哔哩杨士航)_第4张图片

3.Django应用结构

创建一个app
python manage.py startapp article
文档结构如下

Django2.0学习笔记1(哔哩哔哩杨士航)_第5张图片
article文件夹如下
Django2.0学习笔记1(哔哩哔哩杨士航)_第6张图片

打开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写入
Django2.0学习笔记1(哔哩哔哩杨士航)_第7张图片

然后制造迁移
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
输入账号密码
可以看到如下界面

Django2.0学习笔记1(哔哩哔哩杨士航)_第8张图片

添加文章,点击article下的添加文章
Django2.0学习笔记1(哔哩哔哩杨士航)_第9张图片

可以多添加几篇,添加文章后界面如下
Django2.0学习笔记1(哔哩哔哩杨士航)_第10张图片

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/',article_detail),#新添加
    
]

启动django网站
python manage.py runserver
访问如下地址
http://localhost:8000/article/1
(localhost等同于127.0.0.1)
效果如下图

Django2.0学习笔记1(哔哩哔哩杨士航)_第11张图片

打开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))

结果如下图

Django2.0学习笔记1(哔哩哔哩杨士航)_第12张图片

再添加一个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写入如下代码:




    
    文章内容


{{ article_obj.title }}


{{ article_obj.content }}

访问http://localhost:8000/article/1

Django2.0学习笔记1(哔哩哔哩杨士航)_第13张图片

也可以导入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里写入如下代码




    
    文章列表


{% for article in articles %}   
    {#{{ article.title }}#}
    {#
#} {{ article.title }}
{% endfor %}

在mysite里面的urls.py下的path添加如下代码

path('article/',article_list,name="article_list"),

访问http://localhost:8000/article/
结果如下图

Django2.0学习笔记1(哔哩哔哩杨士航)_第14张图片

修改路由,在article下创建urls.py
将mysite下的ruls.py下的

path('article/',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('',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")),
]

仍然可以正常访问。


Django2.0学习笔记1(哔哩哔哩杨士航)_第15张图片

后台定制和修改模型

models.py
在article类下添加如下函数

def __str__(self):
        return "Article:{}".format(self.title)

Django2.0学习笔记1(哔哩哔哩杨士航)_第16张图片

修改admin.py下的代码,注释掉 admin.site.register(Article)
添加如下代码

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    list_display=("id","title","content")
    ordering=("id",)#升序排列,倒叙加-,默认倒序
Django2.0学习笔记1(哔哩哔哩杨士航)_第17张图片

修改模型
修改模型要更新数据库

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
Django2.0学习笔记1(哔哩哔哩杨士航)_第18张图片

创建成功
在article app下的admin.py下的list_display后面添加一个"created_time"字段


Django2.0学习笔记1(哔哩哔哩杨士航)_第19张图片
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
Django2.0学习笔记1(哔哩哔哩杨士航)_第20张图片

外键

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
Django2.0学习笔记1(哔哩哔哩杨士航)_第21张图片

修改字段名

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
Django2.0学习笔记1(哔哩哔哩杨士航)_第22张图片
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

Django2.0学习笔记1(哔哩哔哩杨士航)_第23张图片

显示未被删除的数据
将第二篇文章的的is_deleted值改为True
Django2.0学习笔记1(哔哩哔哩杨士航)_第24张图片

在article app下的views.py的
article_list下的 article=Article.objects.all()改为
articles=Article.objects.filter(is_deleted=False)
Django2.0学习笔记1(哔哩哔哩杨士航)_第25张图片

构建个人博客网站

网站的功能模块

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 随笔 感悟

Django2.0学习笔记1(哔哩哔哩杨士航)_第26张图片

添加三篇博客
在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)

添加如下内容
第一篇博客
随笔
这是我的第一篇博客


Django2.0学习笔记1(哔哩哔哩杨士航)_第27张图片
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内容如下




    
    
    
    我的网站


    

个人博客网站

{% for blog in blogs %}

{{ blog.title }}

{{blog.content}}

{% endfor %}

blog_detail.html内容如下




    
    
    
    {{ blog.title }}


    

{{blog.title}}

{{blog.content}}

blog app文件夹下新建urls.py

from django.urls import path
from . import views
#start with blog
urlpatterns = [
    #http://lcolhost:8000/blog/1
    path('',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/


Django2.0学习笔记1(哔哩哔哩杨士航)_第28张图片

将blog_list.html的

{% for blog in blogs %}
    

{{ blog.title }}

{#修改这一行#}

{{blog.content}}

{% endfor %}

改为下面的代码


    {{ blog.title }}

Django2.0学习笔记1(哔哩哔哩杨士航)_第29张图片

在blog_detail.html下添加如下代码:


Django2.0学习笔记1(哔哩哔哩杨士航)_第30张图片

也可以将blog_list.html也改为以下代码


访问http://localhost:8000/admin/blog/blog/add/
添加一篇文章
标题:第二篇博客
类型:随笔
内容:这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客
这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客这是我的第二篇博客
访问http://127.0.0.1:8000/

Django2.0学习笔记1(哔哩哔哩杨士航)_第31张图片

统计博客数量

在blog_list.html下添加如下代码

一共有{{ blog|length }}篇博客

2.views.py下的blog_list函数下添加一行代码

context["blogs_count"]=Blog.objects.all().count()

在blog_list下添加如下代码

 

一共有{{ blogs_count }}篇文章

Django2.0学习笔记1(哔哩哔哩杨士航)_第32张图片

在blog_list下拓展for循环,在for循环内部添加如下带代码:

{% empty %}

暂时没有博客

{#如果为0篇文章则显示此内容#}

过滤器处理过长文本,在blog_list.html下的

{{blog.content}}

修改为:

{{blog.content|truncatechars:30}}

过长内容则显示为省略号


Django2.0学习笔记1(哔哩哔哩杨士航)_第33张图片

{{|truncatewords:30}}
用来统计英文单词,规则使用空格来辨认
blog_detail.html添加如下带代码:

作者:{{ blog.author}}

发表日期:{{ blog.created_time|date:"Y-m-d h:n:s" }}

分类:{{ blog.blog_type }}

{#时间默认十二进制的#} {#把h改为G/H则为二十四进制#}

官网地址介绍

Django2.0学习笔记1(哔哩哔哩杨士航)_第34张图片

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/',views.blogs_with_type,name="blogs_with_type"),

在templates文件夹下新建blogs_with_type.html,代码如下




    
    
    
    {{blog_type.type_name}}


    
    

{{blog_type.type_name}}

{% for blog in blogs %} {{ blog.title }}

{{ blog.content|truncatechars:30 }}

{% empty %}

暂时没有博客

{# 如果为0篇文章则显示此内容 #} {% endfor %}

修改blog_detail.html文件夹下的

分类:{{ blog.blog_type }}


分类: {{ blog.blog_type }}

Django2.0学习笔记1(哔哩哔哩杨士航)_第35张图片

Django2.0学习笔记1(哔哩哔哩杨士航)_第36张图片
配型为随笔的博客分类

再添加一篇django类型的博客


Django2.0学习笔记1(哔哩哔哩杨士航)_第37张图片

Django2.0学习笔记1(哔哩哔哩杨士航)_第38张图片

Django2.0学习笔记1(哔哩哔哩杨士航)_第39张图片

{#注释#}
truncatechars_html自动忽略掉html代码
truncatewords_html
是否信任html:safe

模板嵌套

循环 for
条件 if,ifequeal,ifnotequal
模板嵌套 block,extends,include
注释 {# #}

三个html文件有重复的地方




    



    


blog app下的templates文件夹新建一个html文件,名为base.html内容如下:




    
    {% block title %}{% endblock %}


    
    
{% block content %}{% endblock %}

blog_detail.html文件修改为如下内容:

{% extends 'base.html' %}

{% block title %}
    {{ blog.title }}
{% endblock %}

{% block content %}
    

{{blog.title}}

作者:{{ blog.author}}

{{blog.content}}

发表日期:{{ blog.created_time|date:"Y-m-d h:n:s" }}

分类: {{ blog.blog_type }}

{% endblock %}

blog_list.html内容修改为:

{% extends 'base.html' %}
{#页面标题#}
{% block title %}
    我的网站
{% endblock %}
{#页面内容#}
{% block content %}
    {% for blog in blogs %}
    
            {{ blog.title }}
    
    

{{ blog.content|truncatechars:30 }}

{% empty %}

暂时没有博客

{# 如果为0篇文章则显示此内容 #} {% endfor %}

一共有{{ blogs_count }}篇文章

{% endblock %}

blogs_with_type.html修改为如下内容:

{% extends 'base.html' %}
{#页面标题#}
{% block title %}
    {{blog_type.type_name}}
{% endblock %}
{#页面内容#}
{% block content %}
    

{{blog_type.type_name}}

{% for blog in blogs %} {{ blog.title }}

{{ blog.content|truncatechars:30 }}

{% empty %}

暂时没有博客

{# 如果为0篇文章则显示此内容 #} {% endfor %} {% endblock %}

python manage.py runserver
访问http://127.0.0.1:8000 可以正常访问

Django2.0学习笔记1(哔哩哔哩杨士航)_第40张图片

全局模板文件夹设置

在项目的根目录下,新建templates文件夹


Django2.0学习笔记1(哔哩哔哩杨士航)_第41张图片

打开settings.py文件
TEMPLATES下修改'DIRS': []为:

'DIRS': [
        os.path.join(BASE_DIR,'templates'),
    ],

把base.html移动到全局的templates文件夹下

Django2.0学习笔记1(哔哩哔哩杨士航)_第42张图片

访问 http://lcoalhost:8000 如下图
Django2.0学习笔记1(哔哩哔哩杨士航)_第43张图片

模板文件设置建议
想任意迁移app,templates建议放在app文件夹里面
app为项目工作,可以放在全局的templates文件夹下,一般在templates文件夹下新建文件夹名字命名为app的名字即可
Django2.0学习笔记1(哔哩哔哩杨士航)_第44张图片

修改blog app下views.py的模板引用



访问 http://lcoalhost:8000 网站还在正常运行

CSS页面设计

导航栏

logo网站名称+导航
把base.html文件添加两个a标签,代码如下:

首页
博客列表

blog app下的urls.py添加一个路由

path('',views.blog_list,name='blog_list'),

修改首页的处理方法
新建文件命名为views.py保存到mysite文件夹下,


Django2.0学习笔记1(哔哩哔哩杨士航)_第45张图片

输入以下代码:

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

欢迎访问我的网站,随便看

{% endblock %}

访问:http://127.0.0.1:8000/

页面如下:
Django2.0学习笔记1(哔哩哔哩杨士航)_第46张图片

页面美化:CSS
把base.html添加css代码,总体代码如下:




    
    {% block title %}{% endblock %}


    
    {% block content %}{% endblock %}
    


home.html添加如下代码:

欢迎访问我的网站,随便看

效果如下图


Django2.0学习笔记1(哔哩哔哩杨士航)_第47张图片

引用静态文件

静态文件

css文件
js文件
图片等

新建文件夹名为static,在static文件夹下新建base.css,把base.html里面的css代码粘贴到base.css里面。
在settings.py最后添加如下代码:

STATICFILES_DIRS=[
    os.path.join(BASE_DIR,'static'),
]

在base.html的head里面添加如下代码:

 

第二种方法加载静态文件
在base.html文件下添加如下代码

{% load staticfiles %}

刷新网页,网页没有变化
同理在static文件夹下新建home.css,把home.html文件下的css代码剪切过去,在base.html文件夹下添加一行代码。

{% block header_extends %}{% endblock %}

在home.html文件里面添加一行代码:

{% load staticfiles %}
{% block header_extends %}

{% endblock %}

主题内容
尾注

css框架协助前端布局

下载bootstrap3,官网
在static文件夹下新建bootstrap文件夹,放入下载的css、js文件

Django2.0学习笔记1(哔哩哔哩杨士航)_第48张图片

打开base.html,添加对bootstrap的css和js的引用,



下载最新版的jquery官网,放到static文件夹下

Django2.0学习笔记1(哔哩哔哩杨士航)_第49张图片

添加对jquery的引用,jquery的引用要放在bootstrap.js的前面



结构如下图:



,在head标签里面添加一个meta标签


 

添加导航栏,在base.html文件夹下添加如下代码:

 

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

结果如下:
Django2.0学习笔记1(哔哩哔哩杨士航)_第50张图片

Django2.0学习笔记1(哔哩哔哩杨士航)_第51张图片

bootstrap响应式布局

修改blog_list.html文件,修改后代码如下

{% extends 'base.html' %}
{#页面标题#}
{% block title %}
    我的网站
{% endblock %}
{# 加载静态文件 #}
{% load staticfiles %}
{# 文件引用 #}
{% block header_extends %}
    
{% endblock %}
{% block nav_blog_active %}active{% endblock %}
{#页面内容#}
{% block content %}
{# 博客列表 (一共有{{ blogs_count }}篇文章)#} {% block blog_list_title %} 博客列表 (一共有{{ blogs_count }}篇文章) {% endblock %}
{% for blog in blogs %}

{{ blog.title}}

{{ blog.blog_type }} {{ blog.created_time|date:'Y-m-d' }}

{{ blog.content|truncatechars:50 }}

{% empty %}{# 如果为0篇文章则显示此内容 #}

暂时没有博客

{% endfor %}
{% endblock %}

修改blog app下的blog_list函数,添加代码如下

context["blog_types"]=BlogType.objects.all()

把全局templates文件夹下的blog文件夹剪切粘贴到blog app下的templates文件夹下


Django2.0学习笔记1(哔哩哔哩杨士航)_第52张图片

在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文件夹


Django2.0学习笔记1(哔哩哔哩杨士航)_第53张图片

修改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 }}篇文章
    返回博客列表
{% 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 %}
    
{% endblock %}

{% block content %}
    

{{blog.title}}

  • 作者:{{ blog.author}}
  • 分类: {{ blog.blog_type }}
  • 发表日期:{{ blog.created_time|date:"Y-m-d h:n:s" }}
{{blog.content}}
{% endblock %}

最终效果入下:


Django2.0学习笔记1(哔哩哔哩杨士航)_第54张图片

Django2.0学习笔记1(哔哩哔哩杨士航)_第55张图片

Django2.0学习笔记1(哔哩哔哩杨士航)_第56张图片

分页和shell命令行模式

新增或编辑博客内容
博客文章数量较多导致加载过慢,分页加载
shell命令行模式添加博客
1、cmd python manage.py shell

#添加一篇文章
from blog.models import Blog
dir()
# ['Blog', '__builtins__']
Blog.objects.all()
# , , ]>
Blog.objects.count()
# 3
Blog.objects.all().count()
# 3
blog=Blog()
dir()
# ['Blog', '__builtins__', 'blog']
Blog.objects.all()
# , , ]>
blog.title="shell下的第一篇博客"
blog.content="shell下的博客内容"
from blog.models import BlogType
BlogType.objects.all()
# , , ]>
BlogType.objects.all()[0]
# 
blog_type=BlogType.objects.all()[0]
blog.blog_type=blog_type
from django.contrib.auth.models import User
User.objects.all()
# ]>
user=User.objects.all()[0]
blog.author=user
blog.save()
Blog.objects.all()
# , , , ]>
访问localhost:8000/admin
Django2.0学习笔记1(哔哩哔哩杨士航)_第57张图片
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=)

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
Django2.0学习笔记1(哔哩哔哩杨士航)_第58张图片

分页

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)
# :1: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list:  QuerySet.
# :1:无序对象列表警告:分页可能会产生与无序object_list不一致的结果: 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
#
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
#
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
"""
, , , ,
 , , , , , ]>
"""
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下的代码:

下的
{% for blog in blogs %}```` 改为{% for blog in page_of_blogs.object_list %}````
新建div,添加如下代码:

Django2.0学习笔记1(哔哩哔哩杨士航)_第59张图片

优化分页展示

页码很多怎么显示
blog app views.py下的blog_list函数代码

paginator=Paginator(blogs_all_list,10) #每十篇进行分页

修改为

paginator=Paginator(blogs_all_list,2) #每2篇进行分页
Django2.0学习笔记1(哔哩哔哩杨士航)_第60张图片

优化:
当前页高亮
不要过多页码选择,凸显页面布局
修改blog_list.html
在{# 全部页码 #}下修改为如下代码:

{% for page_num in page_of_blogs.paginator.page_range %}
    {% if page_num == page_of_blogs.number %}
          
  • {{ page_num }}
  • {% else %}
  • {{ page_num }}
  • {% endif %} {% endfor %}
    Django2.0学习笔记1(哔哩哔哩杨士航)_第61张图片

    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))
    
    Django2.0学习笔记1(哔哩哔哩杨士航)_第62张图片

    Django2.0学习笔记1(哔哩哔哩杨士航)_第63张图片

    在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)
    
    Django2.0学习笔记1(哔哩哔哩杨士航)_第64张图片

    Django2.0学习笔记1(哔哩哔哩杨士航)_第65张图片

    修改blog_list.html文件下的{#全部代码#}下的{% else %}代码

    {% if page_num == '...' %}
        
  • {{ page_num }}
  • {% else %}
  • {{ page_num }}
  • {% endif %}

    找到blog_list.html里面的一共有多少篇博客的代码,剪切粘贴至前面的新建的

    标签里面
    代码如下:

     共有{{ page_of_blogs.paginator.count }}篇文章,共{{ page_of_blogs.paginator.num_pages }}页,当前第{{ page_of_blogs.number }}页
    

      上的nav/div添加一个class为mypaginator,修改blog.css
      添加如下代码:

      nav.mypaginator{
      text-align: center;
      }
      
      Django2.0学习笔记1(哔哩哔哩杨士航)_第66张图片

      在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)
      
      Django2.0学习笔记1(哔哩哔哩杨士航)_第67张图片

      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 }}篇文章#}
      
      Django2.0学习笔记1(哔哩哔哩杨士航)_第68张图片

      上下篇博客和按月分类

      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

      {{blog.content}}
      后面添加如下代码:

      {% if previous_blog %} 上一篇:{{ previous_blog.title }} {% else %} 木有了 {% endif %}

      {% if next_blog %} 下一篇:{{ next_blog.title }} {% else %} 木有了 {% endif %}

      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//',views.blogs_with_date,name="blogs_with_date")
      

      打开blog_list.html文件,在

      同级的建立一个

      里面添加如下代码:

      日期归档
        {% for blog_date in blog_dates %}
      • {{ blog_date|date:"Y年-m月" }}
      • {% endfor %}

      在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}}:
          返回博客列表
      {% 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)
      
      Django2.0学习笔记1(哔哩哔哩杨士航)_第69张图片

      Django2.0学习笔记1(哔哩哔哩杨士航)_第70张图片

      博客分类统计

      在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 }})
      

      刷新页面查看:


      Django2.0学习笔记1(哔哩哔哩杨士航)_第71张图片

      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
      

      在日期归档下找到

      在他的
        里面追加一下代码:

        {% for blog_date,blog_count in blog_dates.items %}
            
      • {{ blog_date|date:"Y年-m月" }}({{ blog_count }})
      • {% endfor %}

        刷新页面查看:


        Django2.0学习笔记1(哔哩哔哩杨士航)_第72张图片

      你可能感兴趣的:(Django2.0学习笔记1(哔哩哔哩杨士航))