美文网首页DjangoPython
Django2.0学习笔记1(哔哩哔哩杨士航)

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

作者: 假装我不帅 | 来源:发表于2019-01-06 21:56 被阅读0次

    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
    文档结构如下

    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">&laquo;</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">&raquo;</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 %}
    

    刷新页面查看:


    相关文章

      网友评论

        本文标题:Django2.0学习笔记1(哔哩哔哩杨士航)

        本文链接:https://www.haomeiwen.com/subject/dnderqtx.html