Django学习路线之MySQL驱动安装及简单连接(文末附简单图书管理系统实例)

这一部分算是一个过渡的部分,内容相比于前三部分来说,会少一些,主要是讲讲数据库的安装以及基本的有关数据库的操作。

  1. MySQL驱动程序安装
  2. Django配置连接数据库
  3. 在Django中操作数据库
  4. Python DB API下规范下cursor对象常用接口
  5. 简单图书管理系统实例

在这里插入图片描述

1. MySQL驱动程序安装

我们使用Django来操作MySQL,实际上底层还是通过Python来操作的。因此我们想要用Django来操作MySQL,首先还是需要安装一个驱动程序。

在Python3中,驱动程序有多种选择:

  • pymysql
    纯Python实现的一个驱动。因为是纯Python编写的,因此执行效率不如MySQL-python。并且也因为是纯Python编写的,因此可以和Python代码无缝衔接。
  • mysqlclient
    是MySQL-python的另外一个分支。支持Python3 并且修复了一些bug。
  • MySQL-python
    也就是MySQLdb。是对C语言操作MySQL数据库的一个简单封装。遵循了Python DB API v2
    但是只支持Python2,目前还不支持Python3。
  • MySQL Connector/Python
    MySQL官方推出的使用纯Python连接MySQL的驱动。因为是纯Python开发的。效率不高。

这里我们就使用mysqlclient来操作

mysqlclient安装非常简单,只需要通过pip install mysqlclient即可安装:
在这里插入图片描述
这里需要注意的是,我们要在虚拟环境中安装:
在这里插入图片描述

2. Django配置连接数据库

在操作数据库之前,首先先要连接数据库。这里我们以配置MySQL为例来讲解。

Django连接数据库,不需要单独的创建一个连接对象。只需要在settings.py文件中做好数据库相关的配置就可以了:
在这里插入图片描述
这是默认的配置,ENGINE是数据库引擎,我们可以在以下目录找到Django支持的数据库引擎:
在这里插入图片描述
在这里插入图片描述
因为这里我们使用的是MySQL,所以这里改成:

'ENGINE': 'django.db.backends.mysql'

下面我们需要根据自己的数据库来配置,在这之前,我们打开MySQL,并创建一个数据库

启动phpStudy:
在这里插入图片描述
如果是第一次使用,需要配置连接:
在这里插入图片描述
测试连接成功即可进入界面:
在这里插入图片描述
新建数据库:
在这里插入图片描述
因此name的配置如下:

'NAME': 'django_db'

当然还有一些数据库的密码、端口什么的也需要进行配置,配置如下:

# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases

DATABASES = {
    'default': {
        # 数据库引擎(是mysql还是oracle等)
        'ENGINE': 'django.db.backends.mysql',
        # 数据库的名字
        'NAME': 'django_db',
        # 连接mysql数据库的用户名
        'USER': 'root',
        # 连接mysql数据库的密码
        'PASSWORD': 'root',
        # mysql数据库的主机地址
        'HOST': '127.0.0.1',
        # mysql数据库的端口号
        'PORT': '3306',
    }
}

配置好后,运行manage.py,如果配置错误,是不会报错的,只有在操作数据库时才会报错

3. 在Django中操作数据库

下面新建一个名为book的app,我们在book里操作数据库:
在这里插入图片描述
在项目下的urls.py文件里做映射:
在这里插入图片描述
接着在book里新建urls.py并补充映射的代码:
在这里插入图片描述
在book\views.py里补充对应得方法:
在这里插入图片描述
运行的时候,这里报了一个错:
在这里插入图片描述
可以查看这篇文章:
https://blog.csdn.net/linhai1028/article/details/80300241

处理好后便可以运行了:
在这里插入图片描述
在Django中操作数据库有两种方式。第一种方式就是使用原生sql语句操作,第二种就是使用ORM模型来操作。

在Django中使用原生sql语句操作其实就是使用python db api的接口来操作。如果你的mysql驱动使用的是pymysql,那么你就是使用pymysql来操作的,只不过Django将数据库连接的这一部分封装好了,我们只要在settings.py中配置好了数据库连接信息后直接使用Django封装好的接口就可以操作了

为了操作数据库,这里我们还需要新建一张数据表:
在这里插入图片描述
然后我们手动创建几条数据:
在这里插入图片描述
下面我们回到views.py:

from django.shortcuts import render
from django.http import HttpResponse

# 使用django封装好的connection对象,会自动读取settings.py中数据库的配置信息
from django.db import connection

# Create your views here.

def book(request):
    # 获取游标对象
    cursor = connection.cursor()
    # 拿到游标对象后执行sql语句
    cursor.execute("select * from book")
    # 获取所有的数据
    rows = cursor.fetchall()
    # 遍历查询到的数据
    for row in rows:
        print(row)
    return HttpResponse("图书首页")

运行一下,首先界面是没有效果的:
在这里插入图片描述
但是pycharm里输出了结果:
在这里插入图片描述
以上的execute以及fetchall方法都是Python DB API规范中定义好的。任何使用Python来操作MySQL的驱动程序都应该遵循这个规范。所以不管是使用pymysql或者是mysqlclient或者是mysqldb,他们的接口都是一样的。

4. Python DB API下规范下cursor对象常用接口

description

如果cursor执行了查询的sql代码。那么读取cursor.description属性的时候,将返回一个列表,这个列表中装的是元组,元组中装的分别是:

(name,type_code,display_size,internal_size,precision,scale,null_ok)

其中name代表的是查找出来的数据的字段名称,其他参数暂时用处不大。

rowcount

代表的是在执行了sql语句后受影响的行数。

close

关闭游标。关闭游标以后就再也不能使用了,否则会抛出异常。

execute(sql[,parameters])

执行某个sql语句。如果在执行sql语句的时候还需要传递参数,那么可以传给parameters参数。示例代码如下:

 cursor.execute("select * from article where id=%s",(1,))

fetchone

在执行了查询操作以后,获取第一条数据。

fetchmany(size)

在执行查询操作以后,获取多条数据。具体是多少条要看传的size参数。如果不传size参数,那么默认是获取第一条数据。

fetchall

获取所有满足sql语句的数据。

5. 简单图书管理系统实例

1- 完成图书首页

像上篇文章那样新建一个templates文件夹,并在里面新建index.html:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图书首页</title>
</head>
<body>
    <h2>这是图书首页</h2>
    <ul>
        <li><a href="/">首页</a></li>
        <li><a href="{% url 'book_add' %}">添加图书</a></li>
        <li><a href="{% url 'book_del' %}">删除图书</a></li>
    </ul>

    <table>
        <tr>
            <th>序号</th>
            <th>图书名称</th>
            <th>作者</th>
        </tr>

        {% for item in book %}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ item.1 }}</td>
                <td>{{ item.2 }}</td>
            </tr>
        {% endfor %}

    </table>
</body>
</html>

首页的功能是显示所有图书:
在这里插入图片描述

2- 使用继承

系统中的功能选择是可以复用的,因此我们可以通过继承来减少我们的代码量

这里我们再新建一个base.html作为父类:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

{% block title %}
{% endblock %}

    <ul>
        <li><a href="/">首页</a></li>
        <li><a href="{% url 'book_add' %}">添加图书</a></li>
        <li><a href="{% url 'book_del' %}">删除图书</a></li>
    </ul>

{% block content %}
{% endblock %}

</body>
</html>

那么刚刚的index.html可以改成:

{% extends "base.html" %}

{% block title %}
    <h3>图书首页</h3>
{% endblock %}

{% block content %}
    <table>
        <tr>
            <th>序号</th>
            <th>图书名称</th>
            <th>作者</th>
        </tr>

        {% for item in book %}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ item.1 }}</td>
                <td>{{ item.2 }}</td>
            </tr>
        {% endfor %}

    </table>
{% endblock %}

如果系统需要完成前端的页面的展示,以及图书的增加和删除,那么我们还需要把图书的增加和删除这两个方法补充一下

3- 完善功能

下面我们以增加图书为例,先在book_add.html里完善功能:

{% extends "base.html" %}

{% block title %}
    <h3>图书添加页面</h3>
{% endblock %}

{% block content %}
<form action="" method="post">
    图书名字:<input type="text" name="book_name"><br>
    图书作者:<input type="text" name="book_author"><br>
    <input type="submit" value="提交"><br>
</form>
{% endblock %}

我们保存运行一下:
在这里插入图片描述
这里直接提交后:
在这里插入图片描述
发现报错了,这时我们回到settings.py,把这行注释即可:
在这里插入图片描述

另外,为了检验是否能获取到输入的值,我们在视图函数里接收一下:

def book_add(request):
    book_name = request.POST.get("book_name")
    print(book_name)
    return render(request,"book_add.html")

再来试一下 ,这回能成功接收到了:
在这里插入图片描述
既然可以接收到返回的值,那么下面我们继续完善一下程序,让返回的内容真正添加到数据表里,并且添加完成后自动跳转到首页查看结果:

from django.shortcuts import render,redirect,reverse

def get_cursor():
    return connection.cursor()

def book_add(request):
    if request.method == "POST":
        book_name = request.POST.get("book_name")
        book_author = request.POST.get("book_author")
        print(book_name,",",book_author)
        cursor = get_cursor()
        try:
            cursor.execute("insert into book(`title`,`author`) values('%s','%s')"%(book_name,book_author))
        except:
            return redirect(reverse('index'))
        return redirect(reverse('index'))
    else:
        return render(request,"book_add.html")

效果如下:
在这里插入图片描述
数据表内也发生了相应的变化:
在这里插入图片描述
增加图书的功能如上所示,删除的功能同理,这里就不再多说了

刚刚这些类似一个目录,点击书名应该可以看到图书的详细信息,下面我们把这个功能完善一下

4- 获取图书详情

要实现点击书名就跳转的功能,就要在书名处加个a标签跳转:

index.html:

{% for item in book %}
    <tr>
        <td>{{ forloop.counter }}</td>
        <td><a href="{% url 'book_detail' book_id=item.0 %}">{{ item.1 }}</a></td>
        <td>{{ item.2 }}</td>
    </tr>
{% endfor %}

在book\urls.py里添加映射:

path("book_detail/<int:book_id>",views.book_detail,name="book_detail")

book_detail.html显示图书的详细信息:

{% extends "base.html" %}

{% block title %}
    <h3>图书详情页面</h3>
{% endblock %}

{% block content %}
    <p>序号:{{ book.0 }}</p>
    <p>图书名字:{{ book.1 }}</p>
    <p>图书作者{{ book.2 }}</p>
{% endblock %}

最后在views.py里补充方法:

def book_detail(request,book_id):
    cursor = get_cursor()
    cursor.execute("select * FROM book WHERE id=%d"%book_id)
    book = cursor.fetchone()
    content = {
        'book':book
    }

    return render(request,"book_detail.html",context=content)

效果如下:在这里插入图片描述
点击名为django的图书,显示详情页面:
在这里插入图片描述

当然这里其实可以把删除图书的功能加在这里:

views.py:

def book_del(request,book_id):
    if book_id:
        cursor = get_cursor()
        cursor.execute("DELETE FROM book WHERE id=%d"%book_id)
        return redirect(reverse('index'))
    else:
        return HttpResponse("图书不存在!")

在book_detail.html里添加一个删除图书的a标签跳转:
在这里插入图片描述
这样一来,一个简易的图书管理系统就完成了!

最后总结一下,看看各个页面:

图书首页:
在这里插入图片描述

添加图书页面:
在这里插入图片描述

图书详情页面:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zbp_12138/article/details/106154585