0%

Django与MySQL整合

Django的MVT框架中的V我们已经大致了解了,接下来学习M

准备工作

安装访问MySQL的模块

1
$ pip install mysqlclient

现在不推荐使用pymysql了

建立数据库

1
mysql> CREATE DATABASE `school` CHARACTER SET utf8;

配置连接

settings.py
1
2
3
4
5
6
7
8
9
10
11
12
DATABASES = {
'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+ 'ENGINE': 'django.db.backends.mysql',
+ 'NAME': '<数据库名>',
+ 'USER': '<用户名>',
+ 'PASSWORD': '<密码>',
+ 'HOST': '<地址>',
+ 'PORT': <端口>,
}
}

推荐有条件的使用docker容器

建立模型

这里有两种方式

模型迁移到数据库

阅读官方文档可知,它建表时会自动添加好主键id并自增

image-20200706092607362

创建model

models.py
1
2
3
4
class Teacher(models.Model):
# 如果没有models.AutoField,默认会创建一个id的自增列
user_name = models.CharField(max_length=200)
id_card = models.IntegerField()

详细参数如后台显示名字,注释,设定范围,时间戳,空白允许,空白值,主键……这些请参考官方文档

迁移model到数据库

1
2
$ python manage.py makemigrations [模块名]
$ python manage.py migrate [模块名]

方括号为可选参数,这里我只需要demo

查看

image-20200706104813138

1
2
3
4
5
6
7
8
9
mysql> DESC demo_teacher;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_name | varchar(200) | NO | | NULL | |
| id_card | int(11) | NO | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
3 rows in set (0.05 sec)

迁移过之后,我们会发现在数据库中多了迁移模型的数据表,查看相应表也可以看到我们所建立的字段和类型。

但也多了几张表,其中一张便是django_migrations,这张表即是记录我们在每次执行迁移操作时记录的迁移文件的数据表。

具体记录的是模块和与其对应的迁移文件名。

数据库迁移到模型

建表

1
2
3
4
5
CREATE TABLE `student` (
`id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT "主键id",
`name` VARCHAR ( 16 ) NOT NULL DEFAULT "" COMMENT "姓名",
`school_number` VARCHAR ( 20 ) NOT NULL DEFAULT "" COMMENT "学号",
`gender` VARCHAR ( 4 ) NOT NULL COMMENT "性别");

迁移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ python manage.py inspectdb
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from django.db import models


class Student(models.Model):
name = models.CharField(max_length=16)
school_number = models.CharField(max_length=20)
gender = models.CharField(max_length=4)

class Meta:
managed = False
db_table = 'student'

输出中有一个managed = False,如果需要对数据库进行增删改操作,请把它删除或改为True

我们可以把输出管道传输至models.py

1
$ python manage.py inspectdb >> demo/models.py

Tips

从数据库生成还会产生django_migrations对应的类,我们通过makemigrations生成的文件可以视为一个数据库版本控制系统,因此我把Student和Teacher类都通过模型迁移到数据库的方式处理了。

增删改查(CRUD)

增 Create

用法

1
2
3
4
models.表名.objects.create(参数)
# 或者
# obj = models.对象(参数)
# obj.save()

代码

url映射省略

views.py
1
2
3
def insertTeacher(request):
models.Teacher.objects.create(user_name=request.GET.get('name'), id_card=int(request.GET.get('idCard', default=0)))
return HttpResponse('OK')

效果

1
2
3
4
5
6
7
mysql> select * from demo_teacher;
+----+-----------+---------+
| id | user_name | id_card |
+----+-----------+---------+
| 1 | wei | 111111 |
+----+-----------+---------+
1 row in set (0.06 sec)

查 Read

用法

1
2
3
4
5
6
7
models.对象.objects.all()  # 获取全部记录 返回对象列表
models.对象.objects.values('xxx') # 取xxx字段 返回字典列表
models.对象.objects.values_list('xxx', 'yyy') # 取出xxx和yyy字段,并生成一个元组列表
# models.对象.objects.all()再调用values/values_list可查询生成所有字段对应的字典列表/元组列表
models.对象.objects.get(id=1) # 条件查询
models.对象.objects.order_by("-字段名") # 按字段倒序查询
# 更多操作示例放在示例中

代码

views.py
1
2
3
def selectAllTeacher(request):
li = models.Teacher.objects.all().values()
return JsonResponse(list(li), safe=False)

一个QuerySet对象作为json返回,必须添加safe=False参数

效果

image-20200706140252136

改 Update

用法

1
models.对象.objects.filter(筛选条件).update(更新内容)

代码

view.py
1
2
3
def updateTeacher(request):
models.Teacher.objects.filter(id=request.GET.get('id')).update(user_name=request.GET.get('name'))
return JsonResponse(list(models.Teacher.objects.all().values()), safe=False)

效果

image-20200706140908955

删 Delete

用法

1
models.类名.objects.filter(条件).delete()

代码

view.py
1
2
3
def deleteTeacher(request):
models.Teacher.objects.filter(id=request.GET.get('id')).delete()
return JsonResponse(list(models.Teacher.objects.all().values()), safe=False)

效果

image-20200706141254315

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#获取个数
#
#models.Tb1.objects.filter(name='seven').count()
#大于,小于
#
# models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值
# models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值
# in
#
# models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
# models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
# contains
#
# models.Tb1.objects.filter(name__contains="ven")
# models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
# models.Tb1.objects.exclude(name__icontains="ven")
# range
#
# models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and
# 其他类似
#
# startswith,istartswith, endswith, iendswith,
# order by
#
# models.Tb1.objects.filter(name='seven').order_by('id') # asc
# models.Tb1.objects.filter(name='seven').order_by('-id') # desc
# limit 、offset
#
# models.Tb1.objects.all()[10:20]
# group by
from django.db.models import Count, Min, Max, Sum
# models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

写在最后

还没从Spring Boot的思想中转换出来,一开始想用类似于mybatis手写SQL语句的方法:

1
2
3
4
5
6
def getdata(request):
# 使用SQL
with connection.cursor() as cursor:
cursor.execute('select id, machine, tomcathome, ipaddress, description from tomcatData')
data = dictfetchall(cursor)
return JsonResponse(data, safe=False, json_dumps_params={'ensure_ascii': False})

太憨了,

最让我惊喜的是Django竟然自带热部署,springboot的热部署插件还是收费的

-----------看到底线啦 感谢您的阅读-------------