我们使用Django来操作MySQL,实际上底层还是通过Python来操作的。因此我们想要用Django来操作MySQL,首先还是需要安装一个驱动程序。在Python3中,驱动程序有多种选择。比如有pymysql以及mysqlclient等。这里我们就使用mysqlclient来操作。mysqlclient安装非常简单。只需要通过pip install mysqlclient
即可安装。
常见MySQL驱动介绍:
在操作数据库之前,首先先要连接数据库。这里我们以配置MySQL为例来讲解。Django连接数据库,不需要单独的创建一个连接对象。只需要在settings.py文件中做好数据库相关的配置就可以了。
DATABASES = {
'default': {
# 数据库引擎(是mysql还是oracle等)
'ENGINE': 'django.db.backends.mysql',
# 数据库的名字
'NAME': 'logic',
# 连接mysql数据库的用户名
'USER': 'root',
# 连接mysql数据库的密码
'PASSWORD': 'root',
# mysql数据库的主机地址
'HOST': '127.0.0.1',
# mysql数据库的端口号
'PORT': '3306',
}
}
# 连接Linux服务器MySQL问题:https://blog.csdn.net/qq473179304/article/details/56665364
在Django中操作数据库有两种方式。第一种方式就是使用原生sql语句操作,第二种就是使用ORM模型来操作。
在Django中使用原生sql语句操作其实就是使用python db api的接口来操作。如果你的mysql驱动使用的是pymysql,那么你就是使用pymysql来操作的,只不过Django将数据库连接的这一部分封装好了,我们只要在settings.py中配置好了数据库连接信息后直接使用Django封装好的接口就可以操作了
# 使用django封装好的connection对象,会自动读取settings.py中数据库的配置信息
from django.db import connection
# 获取游标对象
cursor = connection.cursor()
# 拿到游标对象后执行sql语句
cursor.execute("select * from book")
# 获取所有的数据
rows = cursor.fetchall()
# 遍历查询到的数据
for row in rows:
print(row)
以上的execute以及fetchall方法都是Python DB API规范中定义好的。任何使用Python来操作MySQL的驱动程序都应该遵循这个规范。所以不管是使用pymysql或者是mysqlclient或者是mysqldb,他们的接口都是一样的。
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参数。fetchone
:在执行了查询操作以后,获取第一条数据。fetchmany(size)
:在执行查询操作以后,获取多条数据。具体是多少条要看传的size参数。如果不传size参数,那么默认是获取第一条数据。fetchall
:获取所有满足sql语句的数据。项目app文件夹/views.py
from django.shortcuts import render
from django.http import HttpResponse
# 两种连接数据库的方式
from django.db import connection
from pymysql import *
def index(request):
# 第一种连接数据库方式,pymysql连接数据库
# conn = connect(host='127.0.0.1', port=3306, databases='django_db1', user='root', password='root', charset='utf8')
# 第二种连接数据库方式,django中的connection连接数据库
cursor = connection.cursor() # 获取游标对象
cursor.execute("select * from book") # 不会把查询结果直接返回
print(cursor.rowcount) # 执行了sql语句后受影响的行数。
data = cursor.fetchone() # 查询一条数据
datas = cursor.fetchall() # 查询所有数据
data1 = cursor.fetchmany(2) # 查询多条数据
print(data)
# return render(request, 'index.html')
return HttpResponse("首页")
完成图书的增删改查,以及前端的页面的展示
项目文件目录如下:
front/views.py
from django.shortcuts import render, redirect, reverse
from django.http import HttpResponse
# 两种连接数据库的方式
from django.db import connection # mysqlclient
from pymysql import *
'''
def index(request):
# 第一种连接数据库方式,pymysql连接数据库
# conn = connect(host='127.0.0.1', port=3306, databases='django_db1', user='root', password='root', charset='utf8')
# 第二种连接数据库方式,django中的connection连接数据库
cursor = connection.cursor() # 获取游标对象
cursor.execute("select * from book") # 不会把查询结果直接返回
print(cursor.rowcount) # 执行了sql语句后受影响的行数。
data = cursor.fetchone() # 查询一条数据
datas = cursor.fetchall() # 查询所有数据
data1 = cursor.fetchmany(2) # 查询多条数据
print(data)
# return render(request, 'index.html')
return HttpResponse("首页")
'''
# 抽离出来复用代码次数多的,视图函数才需要request参数
def get_cursor():
return connection.cursor()
# 首页
def index(request):
# 连接数据库查询
# cursor = connection.cursor()
cursor = get_cursor() # 查询游标,抽离的复用代码
cursor.execute('select * from book') # 查询book表,原生sql语句
books = cursor.fetchall() # 查询所有
print(books) # ((1, 'xxxx', 20.0), (2, 'tttt', 20.01), (3, 'zzzz', 30.02), (4, 'yyyy', 18.99))
context = {
"books": books,
}
return render(request, 'index.html', context=context)
# 添加图书
def add_book(request):
# 从form表单中获得前端的post请求信息
if request.method == 'POST':
# POST请求,保存数据到数据库
name = request.POST.get('name')
price = request.POST.get('price')
cursor = get_cursor() # 查询游标,抽离的复用代码
# 执行原生的mysql插入语句,values('name','price')是字符串
cursor.execute("insert into book(`name`,`price`) values('%s','%s')" % (name, price))
# 重定向到首页
return redirect(reverse('index'))
else:
# GET请求,显示界面
return render(request, 'add_book.html')
# 图书详情页
def book_detail(request, book_id):
cursor = get_cursor()
cursor.execute("select * from book where id=%s" % book_id)
book = cursor.fetchone()
context = {
"book": book,
}
return render(request, "book_detail.html", context=context)
# 图书删除操作
def book_delete(request, book_id):
if book_id:
cursor = get_cursor()
cursor.execute("delete from book where id= %s" % book_id)
return redirect(reverse("index"))
else:
return render(request, "book_detail.html")
front/urls.py
# -*- encoding: utf-8 -*-
"""
@File : urls.py
@Time : 2020/6/27 21:08
@Author : chen
front/urls.py
"""
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name='index'),
path("add_book/", views.add_book, name='add_book'),
path("book_detail/" , views.book_detail, name='book_detail'),
path("book_delete/" , views.book_delete, name='book_delete'),
]
templates/base.html文件
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<ul>
<li><a href="{% url 'index' %}">首页a>li>
<li><a href="{% url 'add_book' %}">发布图书a>li>
ul>
{% block content %}
{% endblock %}
body>
html>
templates/index.html文件
{% extends 'base.html' %}
{% block content %}
<table>
<tr>
<th>序号th>
<th>图书th>
<th>名字th>
tr>
{% for book in books %}
<tr>
<td>{{ forloop.counter }}td>
<td>{{ book.1 }}td>
<td>{{ book.2 }}td>
tr>
{% endfor %}
table>
{% endblock %}
templates/add_book.html文件
{% extends 'base.html' %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
图书名字:<input type="text" name="name"><br>
图书价格:<input type="text" name="price"><br>
<input type="submit" value="提交">
form>
{% endblock %}
templates/book_detail.html文件
{% extends "base.html" %}
{% block content %}
{% csrf_token %}
<table>
<tr>
<th>序号th>
<th>图书th>
<th>价格th>
<th>操作/删除th>
tr>
<tr>
<td>{{ book.0 }}td>
<td>{{ book.1 }}td>
<td>{{ book.2 }}td>
<br>
<td><a href="{% url 'book_delete' book_id=book.0 %}">删除图书a>td>
tr>
table>
{% endblock %}
随着项目越来越大,采用写原生SQL的方式在代码中会出现大量的SQL语句,那么问题就出现了:
from django.db import models
# 创建一个模型,对应数据库中的一张表
class Book(models.Model):
id = models.AutoField()
name = models.CharField(max_length=100)
author = models.CharField(max_length=100)
price = models.FloatField()
# 一个模型的对象,对应数据库表中的一条数据
book = Book(name="Python",author='龟叔',price=89)
# save方法,保存
book.save()
# delete方法,删除
book.delete()