【django学习】——Django介绍和实战(开发简易版博客网页)

目录

0、视频链接

 1、环境配置

 2、django基本命令

1)常见命令

 2)数据库相关的Django命令

 3、Django项目

1)Django创建项目

 2)项目目录介绍

3)运行初始化的Django项目

 4、Django应用

1)Django项目和Django应用

 2)Django应用目录

(1)创建Django应用

(2)应用目录各文件介绍

 问题1:视图、路由、模型是什么意思?

5、Django视图&Django路由(what、why、how)

1)Django视图(view.py)——创建逻辑函数(数据处理)

 2)Django路由(url.py)——创建URL和函数的映射关系

①路由表和路由

②Django路由表的创建——path

③二级路由——项目路由容器转派到各应用路由容器中

3)request对象和response对象

①request对象——接收客户端返回的请求数据

② Response对象——根据客户端的请求在服务端获得的数据处理后要返回给客户端的数据(响应)

4)一个简单的Django项目(含视图及路由文件修改)——helloworld

 ①应用视图函数编写——获得网页请求,返回“helloworld”

②配置应用层面的路由——获得路由名后,到view.py查找对应的逻辑函数

③配置项目层面的路由——获得URL后,根据路由将截断的URL分配到对应的应用路由表中urls.py

④将APP应用配置到项目中

 ⑥本项目流程

 问题2:什么是Django模型层?

6、Django模型层(models.py)

1)模型层简介(概念和作用)

 2)Django中模型层的配置(settings.py)

7、Django模型的创建——创建博客文章类型(models.py)

1)明确博客文章的组成字段及其类型

2)定义字段

 3)文章模型的定义

4)python manage.py makemigrations生成迁移文件

5)python manage.py migrate 迁移模型到数据库

8、Django shell——交互式环境

1)what&why

 2)how——向数据库中插入一条记录

9、Django admin模块——管理员功能(用于后台修改数据)

1)what&why

 2)how——如何使用admin模块

①创建管理员身份

②运行admin模块

③在admin.py中注册模型

 10、从数据库中获取数据并且返回给浏览器

1)编写代码

 2)整个过程的流程图

 问题3:什么是Django模板(template)

11、django 模板系统

1)模板系统简介

 2)简单的模板例子

3)Django模板系统的基本语法

12、boostrap以及boostrap栅格系统

13、【实操】利用boostrap和Django模板实现博客系统

1)博客页面设计(博客首页+博客文章详情页)

2)博客首页设计

①书写博客首页的模板(HTML)

 ②修改视图文件函数返回模板变量值

 ③设置路由

④python manage.py runserver运行

3)博客文章详情页设计

①书写博客首页的模板(HTML)

  ②修改视图文件函数返回模板变量值

 ③设置路由 

④python manage.py runserver运行 

4)实现博客首页跳转至文章详情页

①文章详情页URL链接设计

②修改详情页链接路由设置

③修改视图函数get_detail_page

④为博客首页的文章列表添加链接

5)实现上下篇文章跳转

 ①设计翻页按钮——boostrap翻页组件

 ②给每一个详情页的上下篇文章按钮设置链接

③修改视图函数

 6)实现博客首页分页功能

〇Django分页组件工具——Django.core.paginator.Paginator

①设计分页按钮——boostrap分页组件

 ②设计分页的URL

③修改视图函数

④修改index.html模板

 7)实现最新文章的显示功能

14、总结

15、问题遗留

1)如何将网页上用户输入的信息保存到数据库

2)除了boostrap前端框架是否还有其他前端框架

3)实现一个网页版管理系统


0、视频链接

视频链接:

三小时带你入门Django框架_哔哩哔哩_bilibiliDjango框架是Python语言最热门的Web框架之一。本课程将带你学习Django的项目结构,路由配置,和admin模块等知识点,并且将理论与实践结合,利用Django框架高效便捷,容易上手的特性。带你三小时搭建一个网站,让你快速上手Web开发。如果你有简单的Python语法基础,并且渴望项目实践,那么这门课程你不容错过。海量优质原创课程尽在【慕课网】www.imooc.com还请观众老爷https://www.bilibili.com/video/BV1Sf4y1v77f?p=1

 1、环境配置

Python3.5+

pycharm IDE

Django2.0

安装Django: pip install django==2.0

 测试Django是否安装成功:

终端输入:django-admin

出现下面的图示,不报错即可

 2、django基本命令

1)常见命令

[django]
    check校验项目的完整性
    compilemessages
    createcachetable
    dbshell
    diffsettings
    dumpdata
    flush
    inspectdb
    loaddata
    makemessages
    makemigrations
    migrate
    runserver进入Django的环境,并且运行Django的项目
    sendtestemail
    shell进入Django shell的环境
    showmigrations
    sqlflush
    sqlmigrate
    sqlsequencereset
    squashmigrations
    startapp:启动Django应用
    startproject:启动Django项目
    test执行用例
    testserver

 2)数据库相关的Django命令

 3、Django项目

1)Django创建项目

django-admin startproject 项目名称

django-admin startproject blogWebSystem

创建成功后项目如下所示:

 

 2)项目目录介绍

参考:1、Django框架目录介绍 - 我是旺旺 - 博客园https://www.cnblogs.com/licl11092/p/7595726.html

3)运行初始化的Django项目

python manage.py runserver

 复制链接到网页上打开,出现下面的界面表示创建项目成功

 4、Django应用

1)Django项目和Django应用

 

 

 2)Django应用目录

(1)创建Django应用

Django manager.py startapp 应用名称

Django manager.py startapp blog

 

(2)应用目录各文件介绍

 

 

 问题1:视图、路由、模型是什么意思?

5、Django视图&Django路由(what、why、how)

1)Django视图(view.py)——创建逻辑函数(数据处理)

博客《Django中的视图(view) - rain、 - 博客园》中对视图的解释:

视图就是Django项目下的view.py文件,它的内部是一系列的函数或者是类,用来专门处理客户端访问请求后处理请求并且返回相应的数据,相当于一个中央情报处理系统

视图的作用(总结为两点):

①将网页端(客户端)的请求接收,然后将请求反馈给服务端(服务器、本机);

②将服务端的数据返回给网页端(客户端),并且显示在网页上。

其实就是一个中央数据处理站,服务端和客户端的枢纽

 2)Django路由(url.py)——创建URL和函数的映射关系

①路由表和路由

博客《django路由介绍_越前浩波的博客-CSDN博客_django路由》中对路由的介绍

简单来说,路由就是URL到函数的映射。

        route就是一条路由,它将一个URL路径和一个函数进行映射,例如:

/users        ->  getAllUsers()
/users/count  ->  getUsersCount()

        这就是两条路由,当访问 /users 的时候,会执行 getAllUsers() 函数;当访问 /users/count 的时候,会执行 getUsersCount() 函数

        router 可以理解为一个容器,或者说一种机制,它管理了一组 route

        简单来说,route 只是进行了URL和函数的映射,而在当接收到一个URL之后,去路由映射表中查找相应的函数,这个过程是由 router 来处理的。路由系统的工作总结起来就是:制定路由规则,分析url,分发请求到响应视图函数中。

路由系统的路由功能基于路由表,路由表是预先定义好的url和视图函数的映射记录,换句话说,可以理解成将url和视图函数做了绑定,映射关系有点类似一个python字典:

url_to_view_dic = {'路径1': view_func_1,'路径2': view_func_2,'路径n': view_func_n,...
}

路由表的建立是控制层面,需要在实际业务启动前就准备完毕,即:先有路由,后有业务。
一旦路由准备完毕,业务的转发将会完全遵从路由表的指导:

去往路径1的request --> 被路由器分发到view_func_1函数处理
去往路径2的request --> 被路由器分发到view_func_2函数处理
去往路径n的request --> 被路由器分发到view_func_n函数处理
...

②Django路由表的创建——path

django框架中的工具:path
所有的web请求都将以django项目目录下的urls.py文件作为路由分发主入口,所以如果要完成最简单的路由功能,只需要在此文件中预先配置好路由表即可。path是django v2的工具

# 项目urls.py文件, 目前两种工具可以任选使用
re_path(r'home/', views.index)
path('articles/<int:id>', views.show_article) 

路由表示例:

# urls.py文件urlpatterns = [# 自带后台管理页面路由path('admin/', admin.site.urls),# 新增path('add/author/$', views.add_author),path('add/book/$', views.add_book),# 删除path('delete/author/(\d+)', views.delete_author),path('delete/book/(\d+)', views.delete_book),# 修改path('edit/author/(\d+)', views.edit_author),path(r'edit/book/(\d+)', views.edit_book),
]

注:在Django中分为两种路由,一种是应用层面的路由,一种是Django项目层面的路由

③二级路由——项目路由容器转派到各应用路由容器中

Django 二级路由工具:include

二级路由的意思就是把项目urls文件中的路由整理划分,分布到各自的应用目录urls文件中

  • 1、降低项目urls路由文件中路由数量,由各自应用urls路由文件承担
  • 2、解耦整个项目的路由表,出现路由问题的时候可以单独在二级路由表中处理
  • 3、多级路由以树形结构执行查询,在路由数量很大的时候,可以比单路由表有更快的查询速度
re_path(r'game/', include('game_app.urls')),
re_path(r'chat/', include('chat_app.urls')),
re_path(r'vidio/', include('vidio_app,urls'),

用include实现二级路由表,二级路由会将在一级路由匹配到的url截断后再发送给子路由表继续匹配。以如下一级路由表为例,如果服务器收到一个http://www.xxx.com:8080/game/user/add/?name=a&pswd=b的请求,首先会匹配一级路由表中的game/并将截断后的user/add/发送到二级路由表继续匹配

如上所述,先获得game/,截断后的user/add/发送到game_app.urls路由表中进行下一步的路由表进行匹配

3)request对象和response对象

①request对象——接收客户端返回的请求数据

  当一个页面数据被请求时,Django就会将请求的所有数据自动传递给约定俗称的request这个参数,而我们只需要拿到这个参数并对其进行一系列的操作即可获得所有与操作有关的数据

操作request对象的相应方法

  • path_info     返回用户访问url,不包括域名
  • method        请求中使用的HTTP方法的字符串表示,全大写表示。
  • GET              包含所有HTTP  GET参数的类字典对象
  • POST           包含所有HTTP POST参数的类字典对象
  • body            请求体,byte类型 request.POST的数据就是从body里面提取到的

② Response对象——根据客户端的请求在服务端获得的数据处理后要返回给客户端的数据(响应)

与由Django自动创建的HttpRequest对象相比,HttpResponse对象是我们的职责范围了。我们写的每个视图都需要实例化,填充和返回一个HttpResponse

HttpResponse类位于django.http模块中。

4)一个简单的Django项目(含视图及路由文件修改)——helloworld

要做的事情其实就是打开Django项目后,在链接上增加/user后,能够通过视图函数得到响应值“helloworld”,并且显示在html中

流程:

  • 输入URL
  • 将URL传递给项目的urls.py
  • 根据URL的一级路由和项目的urls.py中的映射表将URL分配到对应的应用的urls.py文件
  • 根据URL的二级路由和应用的urls.py中的映射表将URL分配到下一级应用的urls.py文件
  • ...
  • 最后根据最后一级应用的urls.py文件的映射表调用view.py中的函数
  • view.py中的函数接收由上述步骤得到的请求参数request,获得响应数据reponse
  • 然后将Reponse响应数据返回到浏览器中

 ①应用视图函数编写——获得网页请求,返回“helloworld”

打开应用目录下的view.py文件,修改如下:

from django.shortcuts import renderfrom django.http import HttpResponse# Create your views here.def hello_world(request):# 这里不能直接返回字符串,而是需要将字符串传入到HttpResponse类中,实例化响应类后进行返回return HttpResponse("hello world") 

其中request是客户端请求回来的参数对象,Reponse是服务端返回的响应对象

②配置应用层面的路由——获得路由名后,到view.py查找对应的逻辑函数

在应用里面新建一个urls.py文件,作为路由配置文件的编写

from django.urls import path
from views import hello_worldurlpatterns = [# 当指派到本应用的路由一级路由名为hello_world时,调用view.py中的hello_world函数path('hello_world',hello_world)
]

③配置项目层面的路由——获得URL后,根据路由将截断的URL分配到对应的应用路由表中urls.py

打开项目的urls.py文件

from django.contrib import admin
from django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls),# 将URL分配到对应的APP当中进行二级路由,这里是将其分配到blob.urls中path("user/",include("blob.urls"))
]

④将APP应用配置到项目中

打开项目的settings.py文件

其中blog.apps.BlogConfig是在创建APP的时候生成的,可以查看应用层的apps.py文件

⑤运行项目——python manage.py runserver

修改链接最后运行得到下图结果

 ⑥本项目流程

 问题2:什么是Django模型层?

6、Django模型层(models.py)

模型层其实就是Python类,主要的作用是与数据库进行数据交互,在数据库和视图之间,类似于DAO(data access object)的作用。

注:创建一个模型,其实就是根据网页的元素设计一张数据表,确定数据表的字段、字段类型、主键等参数

1)模型层简介(概念和作用)

 2)Django中模型层的配置(settings.py)

setting.py文件——DATABASES字典

具体Django模型数据库配置可见:

Settings | Django documentation | Djangohttps://docs.djangoproject.com/en/2.0/ref/settings/#databases支持的驱动有:

 配置mysql数据库(将下面的postgresql改成mysql即可):

7、Django模型的创建——创建博客文章类型(models.py)

模型的创建:数据表的设计和同步到数据库中

1)明确博客文章的组成字段及其类型

 

2)定义字段

 

 

 3)文章模型的定义

打开models.py

class Article(models.Model):# 文章idarticle_id = models.AutoField(primary_key=True) # 自增、主键# 文章标题,文本类型article_title = models.TextField()# 文章摘要,文本类型article_abstract = models.TextField()# 文章正文,文本类型article_content = models.TextField()# 文章发布日期,日期类型article_data = models.DateTimeField(auto_now=True) # 自己填充当前日期

4)python manage.py makemigrations生成迁移文件

5)python manage.py migrate 迁移模型到数据库

迁移模型到数据库,即创建了一张表到数据库中

 用可视化软件NAVICAT可以看到在数据库db.sqlite3中已经创建了一个数据表

数据表命名规则:应用名_模型名

 思考:既然模型的创建是数据表的创建,那是否可以直接在可视化软件Navicat中进行数据表的创建呢?

答:如果单单从数据表的创建来看是可以的,但是我们在使用命令python manage.py migrate进行模型的迁移时有可能不单单创建了数据表,还可能对其他文件的一些参数进行了修改,当然这个目前还不确定。

8、Django shell——交互式环境

1)what&why

 

 2)how——向数据库中插入一条记录

python manage.py shell进入Django shell环境

# 利用Django shell向数据库中插入一条记录,即创建一篇文章

>>> a = Article()    # 类实例化

# 设置各个字段的值
>>> a.article_title = "test django shell"
>>>  a.article_abstract = "abstract"
>>> a.article_abstract = "abstract"
>>> a.article_content = "test django shell content"

# 保存记录到数据库中
>>> a.save()

>>>
# 获取模型Article中所有的记录,即获取数据表中所有的记录
>>> articles = Article.objects.all()
>>> artice = articles[0]
>>> print(artice.title)
# 打印指定数据表的某一记录的字段值
>>> print(artice)
Article object (1)
>>> print(artice.article_title)
test django shell

 小结:利用Django shell进行文章的创建(记录的插入非常的麻烦)

9、Django admin模块——管理员功能(用于后台修改数据)

1)what&why

 

 2)how——如何使用admin模块

①创建管理员身份

python manage.py createsuperuser

②运行admin模块

python manage.py runserver

 输入账号密码

 我们看到了可以管理用户和groups,但是没有看到articles,这是因为我们还没有将模型注册到admin模块中,因此在admin身份登录后看不到

③在admin.py中注册模型

from django.contrib import admin# Register your models here.# 导入模型
from blog.models import Articleadmin.site.register(Article)

 再次执行②

 

 但是可以看到每篇文章的标题显示的都是object格式,无法知道具体文章,因此我们需要在创建模型的时候将文章的title返回,这样就可以显示文章标题了

models.py

class Article(models.Model):# 文章idarticle_id = models.AutoField(primary_key=True) # 自增、主键# 文章标题,文本类型article_title = models.TextField()# 文章摘要,文本类型article_abstract = models.TextField()# 文章正文,文本类型article_content = models.TextField()# 文章发布日期,日期类型article_data = models.DateTimeField(auto_now=True) # 自己填充当前日期def __str__(self):return self.article_title

 10、从数据库中获取数据并且返回给浏览器

这里涉及到多个文件

view.py:定义一个函数,从模型文件models.py中获得模型,并且通过模型获得模型的数据,返回数据给浏览器;

models.py:定义了模型,实则就是一张数据表,可以轻松的从数据表中获取数据,然后视图

urls.py:定义路由,根据路径分配到其他地方,然后调用相应的视图函数

1)编写代码

view.py

from django.shortcuts import renderfrom django.http import HttpResponsefrom blog.models import Articledef get_article_contents(request):articles = Article.objects.all()first_article = articles[0]title = first_article.article_titleabstract = first_article.article_abstractcontent = first_article.article_contentreturn_str = "title:%s, abstract:%s, content:%s"%(title,abstract,content)return HttpResponse(return_str)

应用层urls.py

from django.urls import path,include
import blog.viewsurlpatterns = [# 当指派到本应用的路由一级路由名为hello_world时,调用view.py中的hello_world函数path('hello_world',blog.views.hello_world),path('content',blog.views.get_article_contents)
]

项目层urls.py

rom django.contrib import admin
from django.urls import path,includeurlpatterns = [path('admin/', admin.site.urls),# 将URL分配到对应的APP当中进行二级路由,这里是将其分配到blob.urls中path("blog/",include("blog.urls"))
]

 2)整个过程的流程图

 问题3:什么是Django模板(template)

11、django 模板系统

小结:模板系统其实就是一个文本,内容包含了必要的HTML标签以及模板特有的标签占位符组成的。即将之前的HTML文件中的内容用变量来代替了,作为一个HTML模板来使用,等需要使用的时候,只需要向HTML中的变量提供数据即可,这个过程也叫做渲染模板

1)模板系统简介

Django模板是一个string文本,它用来分离一个文档的展现和数据
模板定义了placeholder和表示多种逻辑的tags来规定文档如何展现
通常模板用来输出HTML,但是Django模板也能生成其它基于文本的形式

 

 2)简单的模板例子

<html><head><title>Ordering notice</title></head><body><p>Dear {{ person_name }},</p><p>Thanks for placing an order from {{ company }}. It's scheduled toship on {{ ship_date|date:"F j, Y" }}.</p><p>Here are the items you've ordered:</p><ul>{% for item in item_list %}<li>{{ item }}</li>{% endfor %}</ul>{% if ordered_warranty %}<p>Your warranty information will be included in the packaging.</p>{% endif %}<p>Sincerely,<br />{{ company }}</p></body></html>

这个模板本质上是HTML,但是夹杂了一些变量和模板标签

  • {{}}包围的是变量,如{{person_name}},这表示把给定变量的值插入
  • {%%}包围的是块标签,如{%if ordered_warranty%}

        块标签的含义很丰富,它告诉模板系统做一些事情
        在这个例子模板中包含两个块标签:

        for标签表现为一个简单的循环结构,让你按顺序遍历每条数据
        if标签则表现为逻辑的if语句
        在这里,上面的标签检查ordered_warranty变量的值是否为True
        如果是True,模板系统会显示{%if ordered_warranty%}和{%endif%}之间的内容
        否则,模板系统不会显示这些内容
        模板系统也支持{%else%}等其它逻辑语句

  • 上面还有一个过滤器的例子,过滤器是改变变量显示的方式

        上面的例子中{{ship_date|date:"F j, Y"}}把ship_date变量传递给过滤器
        并给date过滤器传递了一个参数“F j, Y”,date过滤器以给定参数的形式格式化日期
        类似于Unix,过滤器使用管道字符“|”
        Django模板支持多种内建的块标签,并且你可以写你自己的标签

3)Django模板系统的基本语法

 

12、boostrap以及boostrap栅格系统

其实就是一个前端框架,我们可以利用boostrap系统进行前端网页的设计和布局,以及在boostrap官网上直接复制HTML代码下来用于作为模板

  Bootstrap中文网

​ 

 

 

 可以利用这12份进行布局,比如左右各几份

13、【实操】利用boostrap和Django模板实现博客系统

1)博客页面设计(博客首页+博客文章详情页)

博客首页

博客详情页

2)博客首页设计

在应用下创建templates文件夹,在templates文件夹下创建blog(应用名)文件夹,blog下创建index.html文件

编辑index.html文件,引入boostrap相关资源,进入官网点击起步复制相关代码(这里引入的资源是css和JavaScript文件)

①书写博客首页的模板(HTML)

含有变量:article_list和top_article_list

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><!--插入boostrap的相关资源--><!-- 最新版本的 Bootstrap 核心 CSS 文件 --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd"crossorigin="anonymous"></script>
<!--    <link rel="stylesheet" href="index.css">--><title>定义自己的一个博客网站</title></head>
<body>
<!--定义博客首页的标题部分-->
<div class="container page-header"><h1>三小时入门<small>——by zls</small></h1>
</div>
<!--定义博客首页主体部分-->
<div class="container page-body"><!--定义主体部分显示文章列表部分,占9份--><div class="col-md-9" role="main"><div class="body-main"><!-- 每个文章的信息用一个块来表示-->{% for article in article_list %}<div><h2>{{article.article_title}}</h2><p>{{article.article_content}}</p></div>{% endfor %}</div></div><!--定义主体部分显示最近文章列表部分,占3份--><div class="col-md-3" role="complementary"><h2>最新文章</h2>{% for top_article in top_article_list %}<h4><a href="#">{{top_article.article_title}}</a> </h4>{% endfor %}</div></div>
</body>
</html>

 ②修改视图文件函数返回模板变量值

from django.shortcuts import renderfrom django.http import HttpResponsefrom blog.models import Article# 从数据库获得所有数据填充到HTML模板中
# 其中render函数就是将变量值数据喂给指定模板
def get_detail_page(request):all_articles = Article.objects.all()return render(request,"blog/index.html",{'article_list':all_articles,'top_article_list':all_articles})

 ③设置路由

from django.urls import path,include
import blog.viewsurlpatterns = [# 当指派到本应用的路由一级路由名为hello_world时,调用view.py中的hello_world函数path('hello_world',blog.views.hello_world),path('content',blog.views.get_article_contents),path("index",blog.views.get_detail_page)
]

 项目层面的路由不变

④python manage.py runserver运行

3)博客文章详情页设计

在应用下templates文件夹的blog(应用名)文件夹,blog下创建page_detail.html文件

编辑page_detail.html文件,引入boostrap相关资源,进入官网点击起步复制相关代码(这里引入的资源是css和JavaScript文件)

①书写博客首页的模板(HTML)

含有变量:cur_article

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><!--插入boostrap的相关资源--><!-- 最新版本的 Bootstrap 核心 CSS 文件 --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous"><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd"crossorigin="anonymous"></script><link rel="stylesheet" href="../index.css"><title>文章标题1</title></head>
<body>
<!--定义博客文章详情页的标题部分-->
<div class="container page-header"><h1>{{cur_article.article_title}}</h1>
</div>
<!--定义博客详情页主体部分-->
<div class="container page-body"><div class="body-main"><p>{{cur_article.article_content}}</p></div>
</div>
</body>
</html>

  ②修改视图文件函数返回模板变量值

# 选取指定文章的内容,这里以第一篇为例
def get_detail_page(request):cur_article = Article.objects.all()[0] # 取第一篇文章return render(request,'blog/page_detail.html',{"cur_article":cur_article,})

 ③设置路由 

urlpatterns = [# 当指派到本应用的路由一级路由名为hello_world时,调用view.py中的hello_world函数path('hello_world',blog.views.hello_world),path('content',blog.views.get_article_contents),path("index",blog.views.get_index_page),path("detail",blog.views.get_detail_page),
]

④python manage.py runserver运行 

4)实现博客首页跳转至文章详情页

①文章详情页URL链接设计

前面设计的详情页URL链接是:http://127.0.0.1:8000/blog/detail

为了能够让每一个详情页URL独一无二,这里将文章的article_id作为唯一标识,其实就是数据表的主键,设计后URL链接为:http://127.0.0.1:8000/blog/detail/{article_id}

②修改详情页链接路由设置

urlpatterns = [# 当指派到本应用的路由一级路由名为hello_world时,调用view.py中的hello_world函数path('hello_world',blog.views.hello_world),path('content',blog.views.get_article_contents),path("index",blog.views.get_index_page),path("detail/<int:article_id>",blog.views.get_detail_page),
]

③修改视图函数get_detail_page

# 选取指定文章的内容
def get_detail_page(request,article_id):all_articles = Article.objects.all()cur_article = Nonefor article in all_articles:# 遍历所有文章,若文章id和指定的id一样时,获取文章,停止遍历if article.article_id == article_id:cur_article = articlebreakreturn render(request,'blog/page_detail.html',{"cur_article":cur_article,})

④为博客首页的文章列表添加链接

<a href = URL>...<a>

<div class="body-main"><!-- 每个文章的信息用一个块来表示-->{% for article in article_list %}<div><h2><a href="/blog/detail/{{article.article_id}}">{{article.article_title}}</a> </h2><p>{{article.article_content}}</p></div>{% endfor %}</div>

5)实现上下篇文章跳转

 ①设计翻页按钮——boostrap翻页组件

<nav aria-label="..."><ul class="pager"><li><a href="#">Previous</a></li><li><a href="#">Next</a></li></ul>
</nav>

将上述代码添加到detail_page.html中

<body>
<!--定义博客文章详情页的标题部分-->
<div class="container page-header"><h1>{{cur_article.article_title}}</h1>
</div>
<!--定义博客详情页主体部分-->
<div class="container page-body"><div class="body-main"><p>{{cur_article.article_content}}</p><div><nav aria-label="..."><ul class="pager"><li><a href="#">上一篇:{{previous_article.article_title}}</a></li><li><a href="#">下一篇:{{next_article.article_title}}</a></li></ul></nav></div></div>
</div>
</body>

 ②给每一个详情页的上下篇文章按钮设置链接

blog/detail/article_id

<li><a href="/blog/detail/{{previous_article.article_id}}">上一篇:{{previous_article.article_title}}</a></li>
<li><a href="/blog/detail/{{next_article.article_id}}">下一篇:{{next_article.article_title}}</a></li>

③修改视图函数

# 选取指定文章的内容
def get_detail_page(request,article_id):all_articles = Article.objects.all()cur_article = Noneprevious_article = Nonenext_article = Nonefor index,article in enumerate(all_articles):# 遍历所有文章,若文章id和指定的id一样时,获取文章,停止遍历if article.article_id == article_id:cur_article = article# 当当前页是第一页且不是最后一页时,没有上一页if index == 0 and index != len(all_articles)-1:previous_article = articlenext_article = all_articles[index+1]# 当当前页是最后一页且不是第一页时,没有下一页elif index != 0 and index == len(all_articles)-1:previous_article = all_articles[index-1]next_article = article# 当只有一篇文章时elif index == 0 and index == len(all_articles)-1:previous_article = articlenext_article = articleelse:previous_article = all_articles[index-1]next_article = all_articles[index+1]breakreturn render(request,'blog/page_detail.html',{"cur_article":cur_article,"previous_article":previous_article,"next_article":next_article,})

 6)实现博客首页分页功能

〇Django分页组件工具——Django.core.paginator.Paginator

功能:可以将一个列表按照指定的长度分割成多个子列表

p = Paginator(列表,每页的数目)

属性:

p.num_page:分成了多少页

p.count:列表的长度

p_index = p.page(index):表示取得第index页的对象

p_index.object_list:取得第index页的数据

p_index.has_next():判断是否有下一页,有返回True,没有返回false

p_index.has_previous():判断是否有上一页,有返回True,没有返回false

①设计分页按钮——boostrap分页组件

<nav aria-label="Page navigation"><ul class="pagination"><li><a href="#" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li><li><a href="#">1</a></li><li><a href="#">2</a></li><li><a href="#">3</a></li><li><a href="#">4</a></li><li><a href="#">5</a></li><li><a href="#" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li></ul>
</nav>

将上面的分页HTML加入到index.html中

        <!--分页功能--><div class="body-footer"><div class="col-md-4 col-md-offset-3"><nav aria-label="Page navigation"><ul class="pagination"><li><a href="#" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li><li><a href="#">1</a></li><li><a href="#">2</a></li><li><a href="#">3</a></li><li><a href="#">4</a></li><li><a href="#">5</a></li><li><a href="#" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li></ul></nav></div></div></div>

 ②设计分页的URL

可以参考详情页翻页的设计:blog/index/article_id

但是为了学习新知识,这里使用的是:blog/index?page=article_id的方式设计URL

?page=。。。问号后面的参数可以通过request.GET.get('page')来获取得到

③修改视图函数

# 从数据库获得所有数据填充到HTML模板中
# 其中render函数就是将变量值数据喂给指定模板
def get_index_page(request):# 根据请求的参数获得请求的是第几页page = request.GET.get("page")# 得到第几页的参数if page:page = int(page)else:page = 1# 获取所有的文章articles = Article.objects.all()# 利用Django分页组件将文章列表进行分页,每页显示3个文章简介paginator = Paginator(articles, 3)# 根据page获得当前页需要显示的文章页cur_page_articles = paginator.page(page)# 总页数total_page_num = paginator.num_pages# 设置上一页,下一页# 如果当前页有下一页则下一页加1,否则设置为当前页if cur_page_articles.has_next():next_page = page + 1else:next_page = page# 如果当前页有上一页则上一页减1,否则设置为当前页if cur_page_articles.has_previous():previous_page = page - 1else:previous_page = pagereturn render(request,"blog/index.html",{'article_list':cur_page_articles,'top_article_list':articles,'page_num':range(1,total_page_num+1), # 总页数'previous_page':previous_page,"next_page":next_page})

④修改index.html模板

        <!--分页功能--><div class="body-footer"><div class="col-md-4 col-md-offset-3"><nav aria-label="Page navigation"><ul class="pagination"><li><a href="/blog/index?page={{previous_page}}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>{% for num in page_num %}<li><a href="/blog/index?page={{num}}">{{num}}</a></li>{% endfor %}<li><a href="/blog/index?page={{next_page}}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li></ul></nav></div></div></div>

总共7篇文章,每一页显示3篇文章,分成了3页

 7)实现最新文章的显示功能

修改view.py函数即可

# 获取所有的文章articles = Article.objects.all()# 获取按照时间排序的的最新的5篇文章,根据发布日期字段进行降序排序top_article_list = Article.objects.order_by("-article_data")[:5]

 

14、总结

 设计一个网页的流程:

  • 创建项目
  • 创建应用
  • 网页布局设计
  • 模型设计(数据表设计)
  • 根据布局设计网页模板(templates)
  • 设计视图函数view.py
  • 利用模板和视图进行渲染(喂数据)

本项目目录总览:

 

15、问题遗留

1)如何将网页上用户输入的信息保存到数据库

2)除了boostrap前端框架是否还有其他前端框架

3)实现一个网页版管理系统

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/255619.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

求最大子数组03

题目: 返回一个二维整数数组中最大联通子数组的和。 要求&#xff1a; 1. 输入一个二维整形数组&#xff0c;数组里有正数也有负数。 求所有子数组的和的最大值。要求时间复杂度为O(n)。 2.程序要使用的数组放在一个叫 input.txt 的文件中&#xff0c; 文件格式是: 数组的行…

纠错——【Singleton array array(0.2) cannot be considered a valid collection.】

# 将数据集按照比例划分为训练集和测试集 def split_datas(datas,labels,random_state1,train_size0.9,test_size0.1):train_data, test_data, train_label, test_label sklearn.model_selection.train_test_split(datas,labels,random_staterandom_state,# 作用是通过随机数来…

Android Studio 模拟器 不要皮肤,效果更好

新建或者编辑虚拟机时&#xff0c;皮肤选择“No Skin”即可&#xff0c;第二张图片就是无皮肤的效果&#xff0c;看着更爽啊。 转载于:https://www.cnblogs.com/toSeeMyDream/p/6265501.html

JAVA 笔记(三)

NullPointerException:空指针异常 原因&#xff1a;数组已经不再指向堆内存了。而你还用数组名去访问元素。对于查找问题&#xff0c;如果找到就返回其索引值&#xff0c;如果找不到就要返回一个负数&#xff08;一般是负一&#xff09;这是必须的&#xff0c;否则如果找不到&a…

安装Wamp后 Apache无法启动的解决方法

安装Wamp后 Apache无法启动的解决方法&#xff0c;网上的解决方案可以说是五花八门&#xff0c;有些说了一大推&#xff0c;一点作用都起不到。 其实解决方法只需两步&#xff1a; 1、安装路径不能包含有中文&#xff0c;这个我不知道为什么&#xff0c;总之如果安装路径中包含…

【Not all parameters were used in the SQL statement】

在添加游标的时候&#xff0c;添加preparedTrue cursor mydb.cursor(preparedTrue) 感谢博主&#xff1a; 【已解决】Python MySQL: Not all parameters were used in the SQL statement - MoonYear530 - 博客园一、事故缘起 今天构造了一个超过 50 多个参数的 SQL 插入语句…

解决Android Studio报错:DefaultAndroidProject : Unsupported major.minor version 52.0

问题描述 今天使用Android Studio 2.0打开我之前的项目时&#xff0c;编译报了如下错误&#xff1a; Error:Cause: com/android/build/gradle/internal/model/DefaultAndroidProject : Unsupported major.minor version 52.0 其中build.gradle文件内容如下所示&#xff1a; // …

SQL语句:从一个表里按年份统计条目数

比如一个数据表名称叫deploypool&#xff0c; 需要知道里面每一年的记录数&#xff0c; 而add_date字段里有增加记录时的时间&#xff0c; 那么语句如下&#xff1a; SELECT EXTRACT(YEAR from add_date),COUNT(id) FROM deploypool GROUP BY EXTRACT(YEAR from add_date);

Php 与 Json

PHP与JSON 在PHP中存在两个与JSON相关的函数&#xff1a; json_encode($array或$object)函数&#xff1a;把一个数组或对象转化为JSON格式的字符串 json_decode($json,$flag)函数&#xff1a;把一个JSON格式的字符串转化为数组或对象 $flag &#xff1a;true&#xff0c;代表转…

docker supervisor + compose

一&#xff1a; Supervisor Docker 容器在启动的时候开启单个进程&#xff0c;比如&#xff0c;一个 ssh 或者 apache 的 daemon 服务。但我们经常需要在一个机器上开启多个服务&#xff0c;这可以有很多方法&#xff0c;最简单的就是把多个启动命令放到一个启动脚本里面…

【pyqt5学习】——tableWidget学习

设置单元格列宽 self.tableWidget.setColumnWidth(0,200) 设置第一行和表头之间的表格线 self.tableWidget.horizontalHeader().setStyleSheet("QHeaderView::section{background:skyblue;color: black;}")

SUSE团队已将重心偏向GCC 7

2019独角兽企业重金招聘Python工程师标准>>> SUSE的Andreas Jaeger在博客中发表了一篇关于SUSE Linux Enterprise Server 12操作系统更新工具链以及它所带来的新开发工具的博文。文章指出&#xff0c;随着GNU Compiler Collection 7的发布&#xff0c;GCC团队为开发…

eclipse-连接TFS错误 the server to respond with a valid http response解决方法

解决办法 如果普通凭证有多个&#xff0c;则将普通凭证给删除。 转载于:https://www.cnblogs.com/nidongde/p/6277243.html

项目总结——机房收费系统合作版

机房合作就结束了&#xff0c;这次合作开发是第一次与别人一块儿开发一个系统&#xff0c;收获还是蛮大的。以下我总结几点算是经验吧&#xff0c;供以后參考&#xff1a; 管理上1.计划在准备合作开发之前我们三个去找米老师&#xff0c;老师给我们规定了时间。半个月。尽管计划…

CenterOs 防火墙设置

为什么80%的码农都做不了架构师&#xff1f;>>> 1. 重启后生效的 开启&#xff1a; chkconfig iptables on 关闭&#xff1a; chkconfig iptables off 2. 及时生效 开启&#xff1a; service iptables start 关闭&#xff1a; service iptables stop 查看防火墙规则…

提交MTBF eservice以及log注意事项

[DESCRIPTION]提交MTBFeservice需要注意的描述&#xff0c;log事项[SOLUTION]提交MTBF eservice时&#xff0c;请注意1.描述清楚问题现象2. 描述清楚问题发生的时间点3.描述清楚问题发生时在run的case提交log时请注意1.MTBF的log通常会很大&#xff0c;若log太大&#xff0c;只…

Apache Cassandra和Apache Ignite:关系并置和分布式SQL

为什么80%的码农都做不了架构师&#xff1f;>>> 在上一篇文章中&#xff0c;回顾和总结了Cassandra中使用的查询驱动数据模型&#xff08;或者说非常规数据模型&#xff09;方法论的缺陷。事实证明&#xff0c;如果不对查询有深入的了解&#xff0c;通过该方法论将…

【pyradiomics学习】——安装pyradiomics以及简单示例

目录 数据集下载&#xff1a; 示例代码 参考文献&#xff1a; bug修复 运行结果&#xff1a; 数据集下载&#xff1a; https://www.jianguoyun.com/p/DcEwQq0Q45bOBxj09JYC (访问密码: gd8dmv) 示例代码 #!/usr/bin/env python # -*- coding: utf-8 -*- # Time : 20…

【pyradiomics学习】——影像组学特征

目录 1、形状特征&#xff08;14个&#xff09; 2、一阶特征&#xff08;18个&#xff09; 灰度共生矩阵特征&#xff08;24个&#xff09; 灰度区域大小矩阵特征&#xff08;16个&#xff09; 灰度行程矩阵特征&#xff08;16个&#xff09; 邻域灰度差矩阵特…

Hyper-v Server 2012 Release Candidate 部署体验

很多人知道&#xff0c;Microsoft Hyper-V分为两种类型&#xff1a;一种是作为Windows Server的一个组件&#xff0c;另一种是作为虚拟化产品的单独服务器。虽然两者都是技术上的Hyper-V&#xff0c;每个版本的特性和用例各不相同。 Hyper-V Server直接在物理机器硬件上运行&am…