ORM
基础操作
链接
mysql
数据库在
setting.py
中修改数据库配置文件,本教程咱们以MySQL
为例'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'orm', # 要连接的数据库,连接前需要创建好 'USER': 'docker', # 连接数据库的用户名 'PASSWORD': 'docker', # 连接数据库的密码 'HOST': '127.0.0.1', # 连接主机,默认本级 'PORT': 3306 # 端口 默认3306 }
因为django默认你导入的驱动是MySQLdb,可是MySQLdb 对于py3有很大问题,所以我们需要的驱动是PyMySQL 所以,我们只需要找到项目名文件下的init,在里面写入:
import pymysql pymysql.install_as_MySQLdb()
最后通过两条数据库迁移命令即可在指定的数据库中创建表 :
python manage.py makemigrations python manage.py migrate
小技巧:如果想打印orm转换过程中的sql,需要在settings中进行如下配置
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
数据表
利用
Django
的orm
创建数据表,不能创建数据库,用因为Django
是基于数据表的,不是基于数据库的。
创建数据表
我们一般在对应模块下的
model.py
中创建数据表
简单实例:
class Book(models.Model):
'''
创建Book数据表
'''
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
press = models.CharField(max_length=64)
price = models.DecimalField(max_digits=8, decimal_places=2)
anther = models.CharField(max_length=11)
然后执行数据库迁移即可。
添加数据
方式一:
res = models.Book.objects.create(
name ="GO宝典",
press ="南京出版社",
price =1220.3,
anther ="Jack"
)
方式二:
res = Book(
name ="LINUX宝典",
press ="河南出版社",
price =10.3,
anther ="Mosson",
text ="String",
email ="Alvin@cyqit.com"
)
res.save()
查询
基础查询
- all(): 查询所有结果
- filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
- get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
- exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
- order_by(*field): 对查询结果排序
- reverse(): 对查询结果反向排序
- count(): 返回数据库中匹配查询(QuerySet)的对象数量。
- first(): 返回第一条记录
- last(): 返回最后一条记录
- exists(): 如果QuerySet包含数据,就返回True,否则返回False
- values 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列(在QuertSet中存放字典序列)
Book.objects.all().values("title")
- values_list() 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列(在QuertSet中存放元组序列)
Book.objects.all().values_list("title")
- distinct 从返回结果中剔除重复纪录(配合values和values_list使用)
Book.objects.all().distinct()
基于双下划线的模糊查询
Book.objects.filter(price__gt=10, price__lt=20)
- 双下划线的查询列表
__gt : 大于
__lt : 小于
__startswith : 以xxx开头
__in : 在xxx之中
__contains : 包含(区分大小写)
__icontains : 包含(不区分大小写)
__range : 范围
删除
- 删除所有(无返回值)
model_obj.delete()
- 条件删除(返回删除的ID)
Book.objects.all().values("title").delete()
修改
- 条件修改
models.Book.objects.filter(price__gt=1000).update(name="PHP")
多表操作
创建数据
publish_v1 = Publish.objects.get(nid=1)
publish_v2 = Publish.objects.get(nid=2)
publish_v3 = Publish.objects.get(nid=3)
res = Book.objects.create(
title = "MacBook Pro",
publishDate = "2018-09-18",
price = 12.34
)
res.publish.add(publish_v1, publish_v2, publish_v3)
删除数据
res = Book.objects.get(nid=11).delete()
查询
- 一对多(正向查询):
# 查询主键为1的书籍的出版社所在的城市
book_obj=Book.objects.filter(pk=1).first()
# book_obj.publish 是主键为1的书籍对象关联的出版社对象
print(book_obj.publish.city)
- 一对多(反向查询):
res = Publish.objects.get(name="北京出版社").book_set.get(nid=12)
- 一对一(正向查询):
res = Author.objects.filter(name="Alvin").first().antherDetail.telephone
- 一对一(反向查询):
res = AuthorDetail.objects.filter(telephone=16621068505)
for obj in res:
print(obj.author.name)
- 多对多(正向查询):
res = Book.objects.filter(title="PHP").first().anther.all()
for obj in res:
print(obj.name)
- 多对多(反向查询):
res = Author.objects.filter(name="Alvin").first().book_set.all()
for i in res:
print(i.title)
基于双下划线的跨表查询
- 一对多(正向查询)
res = Book.objects.filter(publish__name="北京出版社").all()
- 一对多(反向查询)
res = Publish.objects.filter(name="北京出版社").values_list("book__title")
- 多对多(正向查询):
res = Book.objects.filter(title="PHP").values_list("anther__name")
- 多对多(反向查询):
res = Author.objects.filter(name="Alvin").values_list("book__title")
- 一对一(正向查询):
res = Author.objects.filter(name="Alvin").values_list("antherDetail__addr")
- 一对一(反向查询):
res = AuthorDetail.objects.filter(author__age=23).values_list("author__name")
注:反向查询时,如果定义了related_name ,则用related_name替换表名
聚合查询与分组查询
聚合(aggregate)
res = Book.objects.filter(title="PHP").aggregate(Avg("price"))
分组(annotate)
res = Book.objects.values("price").annotate(c=Count("*"))
附:
from django.db import models
# Create your models here.
class Book(models.Model):
'''
Book数据表
'''
nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5,decimal_places=2)
# 与出版社表建立一对多的关系
publish = models.ManyToManyField(to="Publish",)
# 与Auther建立多对多的关系
anther = models.ManyToManyField(to="Author",)
class Author(models.Model):
'''
Auther表
'''
nid = models.AutoField(primary_key=True)
name = models.CharField( max_length=32)
age = models.IntegerField()
# 与作者详情表建立一对一的关系
antherDetail = models.OneToOneField(to="AuthorDetail", on_delete=models.CASCADE)
class AuthorDetail(models.Model):
'''
作者详情表
'''
nid = models.AutoField(primary_key=True)
birthday = models.DateField()
telephone = models.BigIntegerField()
addr = models.CharField( max_length=64)
class Publish(models.Model):
'''
出版社表
'''
nid = models.AutoField(primary_key=True)
name = models.CharField( max_length=32)
city = models.CharField( max_length=32)
email = models.EmailField()