02django开发博客系统之前端开发

一、数据库增删改查

1. 数据库的增删改查操作

方式1:SQL语句

Python有读取数据库的模块,可以通过SQL语句实现程序和数据库的交互。

方式2:Django内置的API

既然使用Django这个Web框架搭建网站,那么就应该使用Django的规则去操作数据库。Django提供了一系列抽象的API用于数据库的增删改查。

为方便进行数据测试,先新增一个管理员用户,直接在后台管理界面操作即可,如下图:

02django开发博客系统之前端开发

现在有两个后台管理用户,把数据库文件下载到windows下,使用SQLitesPy工具打开。

02django开发博客系统之前端开发

 

1.1 数据表结构和数据模型类的对应关系

  1. 表结构 对应着 数据模型类(模板)
  2. 表的记录 对应着 模型类对象(一条记录就是一个实例化对象)
  3. 记录的字段 对应着 对象的属性(记录中的字段就是对象的属性)

Django内置API

  1. objects方法获得类对象,对应的就是数据表中的一条记录
  2. 类对象中有个get方法,参数是各种查询条件,允许对记录进行筛选
  3. 类对象中有个all方法,返回由类实例组成的序列对象 QuerySet

 

1.2 User数据模型类

这是Django默认有的数据模型类,在数据库文件中,生成对应的数据表名为auth_user。

(1)查询这个表有多少条记录

方式1:SQL语句

SELECT * FROM auth_user

查询结果如下图

02django开发博客系统之前端开发

这两条记录分别对应创建的两个后台管理用户数据信息。

 

方式2:Django内置API

对于Python来说,就是获取所有的对象实例。

1) 先进入shell命令行模式,命令:

python manage.py shell

2) 导出User模块

from django.contrib.auth.models import User

3) 获得所有的对象(获得所有的记录)。

record = User.objects.all()

如下图

02django开发博客系统之前端开发

 

(2)按照某个字段对记录进行筛选

比如,筛选出username这个字段为admin的这条/这些记录。

方式1:SQL语句

SELECT * FROM auth_user WHERE username = 'admin'

查询结果如下图

02django开发博客系统之前端开发

 

方式2:Django内置API

对于Python来说,就是筛选众多对象中符合筛选条件的某个/某些实例。

筛选对象的命令为

user = User.objects.get(username='admin')

筛选出username为admin的这条记录(这个对象)

把对象的各个属性都打印出来

[email protected]:/home/wgp/django_site# python manage.py shell

Python 3.5.2 (default, Apr 16 2020, 17:47:17)

[GCC 5.4.0 20160609] on linux

Type "help", "copyright", "credits" or "license" for more information.

(InteractiveConsole)

>>> from django.contrib.auth.models import User

>>>

>>>

>>> user = User.objects.get(username='admin')

>>>

>>> user

<User: admin>

>>>

 

>>> user.username

'admin'

 

>>> user.id

2

 

>>> user.first_name

'王'

 

>>> user.last_name

'国辉'

 

>>> user.email

'[email protected]'

 

>>> user.date_joined

datetime.datetime(2020, 6, 4, 2, 10, 31, 255887, tzinfo=<UTC>)

 

和使用SQL语句操作数据库的效果是一样的,如下图。

02django开发博客系统之前端开发

 

1.3 BlogArticles数据模型类

这个类是自己写的,同样可以将数据库中的所有记录都读出来。

首先,明确每条记录中有几个字段,字段的取值和含义是什么,可以查看编写的代码,但是更直观的是在数据库管理工具SQLitesPy中直接查看,如下图。

02django开发博客系统之前端开发

编辑了三篇博客,就有三条记录,每条记录中有四个字段,对应着数据模型类里面的四个属性。

02django开发博客系统之前端开发

 

方式1:SQL语句操作数据库

语句

SELECT * FROM blog_blogarticles

结果如下图

02django开发博客系统之前端开发

对数据表中的所有记录按条件(id这个字段的值)进行筛选,语句为:

SELECT * FROM blog_blogarticles WHERE id = '3'

结果如下图

02django开发博客系统之前端开发

取id为3的这条记录的body字段的值,语句为

SELECT body FROM blog_blogarticles WHERE id = '3'

结果如下图

02django开发博客系统之前端开发

 

方式2:Django的API

导出BlogArticles模块

from blog.models import BlogArticles

以id作为记录筛选的条件,打印出每一个记录的title字段,如下图。

02django开发博客系统之前端开发

 

二、显示博客文章标题

1. 编写视图函数

将数据库中的数据放入前段网页上显示之前,首先将数据读出。需要在视图文件view.py中编写视图函数,读出数据库中的数据。

视图文件(views.py)位于APP目录下。

02django开发博客系统之前端开发

文件最初的结构如下图

02django开发博客系统之前端开发

新增读取标题(title)的函数,如下图。

02django开发博客系统之前端开发

视图函数是用来响应用户请求的,它的编写规则是:

1. 函数至少有一个参数,并且名称是request,并且是第一个参数!后面可根据实际情况增加别的参数,命名自由。

2. 函数以return结束,返回结果。render()函数的作用是把数据渲染到指定的模板上,因此它的三个参数含义分别是:参数1必须是request;参数2模板的位置;参数3是传入模板的数据,以字典【键值对】的形式传给模板。

那么到底什么是模板?从上面编写的代码中不难看出,模板其实就是一个html文件。

 

2. 新建模板

用于将用户请求的内容展现在前端的网页,就是模板。模板是一个html文件,并且作为render()的第二个参数。目前对于blog这个app,还没有模板,因此需要新建一个模板,用来显示博客的标题列表。

一系列的命令

mkdir templates

.........................

如下图

02django开发博客系统之前端开发

在app目录下新建一个模板目录,命名为templates;在templates目录下新建一个base.html和一个目录blog,在blog目录下,又新建一个titles.html文件。

规则解析:

(1)模板目录要位于app目录下,templates是Django默认的存放该app的模板目录,因此如果模板目录命名为templates,则render()的第二个参数可以不用指定模板的位置,Django默认到templates目录下去寻找指定的模板,比如这行代码:

return render(request, "blog/title.html", {"blogs:blogs"})

实际上等同于

return render(request, "templates/blog/title.html", {"blogs:blogs"})

如果不以templates来命名模板目录,则传递参数的时候,需要指定切确的模板路径!且需要在项目配置文件setting.py中进行URL的配置。

(2)模板目录下又有一个子目录,这个子目录的名称和app的名称一致。

(3)模板目录下有一个base.html,这是所有模板中的公共模板,在Django的模板文件中,可以有类似于“继承”的功能。

公共模板文件base.html编辑如下

<!DOCTYPE html>

<html lang="zh-cn">

<head>

<meta http-equiv="X-UA-COMPATIBLE" content="IE=Edge">

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>{% block title %}{% endblock %}</title>

<link rel="stylesheet" href="http://necolas.github.io/normalize.css">

<link rel="stylesheet" href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css">

</head>

<body>

         <div>

                   {% block content %}

                   {% endblock %}

         </div>

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js></script>

<script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>

</body>

</html>

除了一些HTML的标签,里面有一个特殊的“块”标签,{% block name %}

开始标签:{% block name %}

块的内容

结束标签:{% endblock %}

与标题列表对应的模板文件:blog/templates/blog/titles.html

内容编辑如下

{% extends "base.html" %}

{% block title %}blog titles{% endblock %}

{% block content %}

<div class="row text-center vertical-middle-sm">

         <h1>我的博客</h1>

</div>

<div class="row">

         <div class="col-xs-12 col-md-8">

                   <ul>

                            {% for blog in blogs %}

                            <li>{{ blog.title }</li>

                            {% endfor %}

                   </ul>

         </div>

         <div class="col-xs-6 col-md-4">

                   <h2>广告</h2>

                   <p>Dango网址:www.itdiffer.com</p>

         </div>

</div>

{% endblock %}

说明

1){% extends "base.html" %}表示该模板继承于基础模板base.html,它可以对基础模板进行扩展,接下来的代码都是基于base.html的,可对其中的部分内容重新实现。

2)在该模板文件中,对“父模板”里面的两个块{%block title%}和{%block content%}进行重写。

3)在该模板中,循环取出从视图函数传过来的所有记录(一条记录就是一个对象)

{% for blog in blogs %}

         <li>{{ blog.title }</li>

{% endfor %}

 

4)使用双层花括号引用变量。

{{ blog.id }}  {{ blog.title }}

 

3. 配置URL

前端访问服务器上的资源,需要明确指出访问哪一个资源,需要配置URL。Django框架中需要配置两次URL,在项目的配置中先配置应用的URL,再配置应用里面的具体的URL。

前端访问后台URL的顺序:先访问到项目的URL,然后请求才会被转向具体某个应用中的URL。

(1)配置当前项目的URL

文件:功能管理目录(位于根目录下且名称与项目相同)中的urls.py

django_site/django_site/urls.py

新增代码

url(r'^blog/', include('blog.urls', namespace='blog', app_name='blog'))

如图

02django开发博客系统之前端开发

在浏览器中输入地址:http://server_ip:端口号/blog ,通过这里的URL配置,该请求会被转向到blog这个应用里面的URL。

(2)配置app的URL

在app目录文件urls.py,内容编辑如下

from django.conf.urls import url

from . import views

 

urlpatterns = [

         url(r"^$", views.blog_title, name="blog_title"),

]

如图

02django开发博客系统之前端开发

views.blog_title声明了响应这个请求[http://server_ip:端口号/blog]的函数。

blog_title函数如何处理该请求?答:返回模板,显示在前端网页上

在文件views.py中,函数blog_title实现如下图

02django开发博客系统之前端开发

 

4. 测试

运行服务器

02django开发博客系统之前端开发

在浏览器中访问,地址栏输入:http://192.168.49.128:8000/blog/

02django开发博客系统之前端开发

 

三、显示文章内容

1. 文章标题超链接

思路:用户单击标题之后,显示文章内容。所以,首先要对文章标题做超链接。修改文件title.html中这部分代码:

文件:django_site/blog/templates/blog/titles.html

<ul>

                            {% for blog in blogs %}

                            <li>{{ blog.title }</li>

                            {% endfor %}

</ul>

 

改为

 

<ul>

                            {% for blog in blogs %}

                            <li><a href="{{ blog.id }}">{{ blog.title }}</a></li>

                            {% endfor %}

</ul>

注:

1)超文本链接的格式  <a href = "…"> 标记超文本链接信息 </a>

2)属性href,于指定超文本链接的目标。

例如

test.html

<!DOCTYPE html>

<html>

<head>

<title>测试超链接</title>

</head>

<body>

         <div>

                   <a href="http://www.baidu.com">百度一下</a>

         </div>

</body>

</html>

浏览器打开html文件,单击“百度一下”,就可以跳到百度搜索引擎首页。

文章标题都有超链接之后,颜色也发生了变化,如下图:

02django开发博客系统之前端开发

 

2. 明确前端网页请求的URL

流程:请求的URL最终是会被转向到视图函数中处理,视图函数解析请求的URL参数,再向指定的模板中传递数据,并返回渲染的结果模板(html)到前端显示。

文章标题的超文本连接目标是博客文章的id,单击文本的时候,浏览器解析到的URL地址应该是:

http://192.168.49.128:8000/blog/1

http://192.168.49.128:8000/blog/2

http://192.168.49.128:8000/blog/3

 

如下图

02django开发博客系统之前端开发

所以,视图函数应该是要根据解析到不同的URL信息,向模板中传入不同的数据,并返回到前端显示。

 

3. 从数据库中读取文章内容

筛选记录的条件是文章的id号

方式1:SQL语句

使用SELECT查询语句就可以实现,命令:

SELECT * FROM blog_blogarticles WHERE id=1

 

SELECT * FROM blog_blogarticles WHERE id=2

 

SELECT * FROM blog_blogarticles WHERE id=3

如下图

02django开发博客系统之前端开发

 

方式2:Django的API

如下图

02django开发博客系统之前端开发

 

4. 编写视图函数

新增一个函数blog_article(),该函数实现:博客文章内容的读取 + 响应请求(解析用户请求的URL,把数据渲染到指定的模板上,并返回结果模板到前端显示)

app目录下的视图文件:django_site/blog/view.py,新增一个blog_article()函数。

from django.shortcuts import render

from .models import BlogArticles

 

# Create your views here.

# Deal with blog titles

def blog_title(request):

         blogs = BlogArticles.objects.all()

         return render(request, "blog/titles.html", {"blogs":blogs})

 

 

#Deal with blog article

def blog_article(request, article_id):

         article = BlogArticles.objects.get(id=article_id)

         pub = article.publish

         return render(request, "blog/content.html", {"article":article, "publish":pub})

 

如图

02django开发博客系统之前端开发

相对处理文章标题来说,处理内容的函数多了一个参数id,后面需要配置URL,将这个id传入视图函数中。

render()函数的第二个参数是模板,目前模板文件还不存在,接下来就要去创建模板文件;参数3指定了视图函数传入模板中的数据内容。

 

5. 新建模板

新建文件content.html,位置:/templates/blog/content.html

编辑内容如下

{% extends "base.html" %}

{% block title %}blog article{% endblock %}

{% block content %}

<div class="row text-center vertical-middle-sm">

         <h1>{{ article.title }}</h1>

</div>

<div class="row">

         <div class="col-xs-12 col-md-8">

                   <p class="text-center"><span>{{ article.author.username }}</span><span style="margin-left: 20px">{{ publish }}</span></p>

                   <div>{{ article.body }}</div>

         </div>

         <div class="col-xs-6 col-md-4">

                   <h2>广告</h2>

                   <p>django官网:https://docs.djangoproject.com/zh-hans/2.2/</p>

         </div>

</div>

{% endblock %}

 

6. 配置URL

对于同一个APP,不需要再次去修改功能管理目录下的URL配置文件:django_site/django_site/urls.py

配置APP的URL即可,文件:django_site/blog/urls.py

新增一行代码,如下:

from django.conf.urls import url

from . import views

 

urlpatterns = [

         url(r"^$", views.blog_title, name="blog_title"),

         url(r'(?P<article_id>\d)/$', views.blog_article, name="blog_article"),

]

如图

02django开发博客系统之前端开发

 

注:正则表达式r'(?P<article_id>\d)/$'获得请求的超文本连接目标(1 、2、 3),即博客文章的id,然后将id赋值给article_id,参数传入视图函数blog_article()。

 

7. 测试

启动服务器

02django开发博客系统之前端开发

先访问博客主页

02django开发博客系统之前端开发

单击标题,即可连接到博客内容页面。

02django开发博客系统之前端开发

 

说明视图函数能正确解析到URL,并将结果返回到前端。

 

8. 处理异常请求

8.1 get_object_or_404()方法

原型:get_object_or_404(klass, *args, **kwargs)

参数解释

klass:数据模型中的某个类

 

*args和**kwargs:查询的条件参数

使用时,要先导出模块:

from django.shortcuts import render, get_object_or_404

当请求的对象不存在时,该方法就会抛出DoesNotExit异常。即URL地址不合法时,网页提示404错误。

修改APP的视图函数,文件:django_site/blog/view.py

如下图

02django开发博客系统之前端开发

假设浏览器中地址栏输入:http://192.168.49.128:8000/blog/8

结果如下图

02django开发博客系统之前端开发