Django-模型层

目录

  1. ORM
  2. 常用字段
  3. 创建表
  4. 增删查改
  5. 表关系
  6. 聚合查询
  7. 分组查询
  8. F和Q
  9. 其他操作

ORM

ORM:对象关系映射,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
ORM在业务逻辑层和数据层之间充当了桥梁的作用
优点:提高了开发效率、不同数据库可以平滑切换
缺点:降低了执行效率

在这里插入图片描述

ORM对应关系表:
在这里插入图片描述

常用字段

models.AutoField(primary_key=True)
	int自增列(主键id),
	必须参数:primary_key=True,
	当model中没有主键id时,会自动创建一个主键id

models.IntegerField()
	整数字段,范围 -2147483648 to 2147483647

models.BigIntegerField()
	大整数字段,范围 -92233720368547758089223372036854775807

models.DecimalField(max_digits, decimal_places)
	小数字段,
	必须参数:max_digits,表示整数部分长度,
	必须参数:decimal_places,表示小数部分长度

models.CharField(max_length)
	字符字段,
	必须参数:max_length,表示字符串的长度

models.DateField(auto_now_add, auto_now)
	日期字段,日期格式 Y-M-D,
	可选参数:auto_now_add=True,自动将创建记录的时间更新到此字段,
	可选参数:auto_now=True,自动将更新记录的时间更新到此字段	

models.DateTimeField(auto_now_add, auto_now)
	日期时间字段,格式 Y-M-D H:M[:S[.u]][TZ],
	可选参数:auto_now_add=True,自动将创建记录的时间更新到此字段,
	可选参数:auto_now=True,自动将更新记录的时间更新到此字段	

models.BooleanField()
	布尔值字段

models.TextField()
	文本字段

models.EmailField()
	邮箱字段
	
models.FileField(upload_to="文件路径", storage=None)
	文件字段,
	必选参数:upload_to参数指定存储文件的位置,存储的路径存到数据库里
	可选参数:storage:存储组件,默认为django.core.files.storage.FileSystemStorage

models.ImageField(upload_to="文件路径", storage=None, width_field=None, height_field=None)
	图片字段,upload_to参数指定存储文件的位置,存储的路径存到数据库里
	可选参数:storage:存储组件,默认为django.core.files.storage.FileSystemStorage
	可选参数:width_field:上传图片宽度保存的字段名
	可选参数:height_field:上传图片高度保存的字段名
	
通用参数:
	default:表示为该字段设置默认值
	null:null=True,表示该字段可以为空
	blank:blank=True,表示该字段可以为空,该字段与null不同,null纯粹与数据库相关,而blank与验证相关,允许表单输入空值
	unique:unique=True,表示该字段必须唯一
	db_index:db_index=True,表示该字段设置为索引
	choices:用于指定一个二元组,组件将是一个选择框,限定选择给定的选项
	verbose_name:字段的自述名

创建表

class Book(models.Model):												# 创建图书表(必须是models.Model的子类)
    id = models.AutoField(primary_key=True)								# 创建主键id,bu
    title = models.CharField(max_length=32)								# 创建标题字段
    price = models.DecimalField(max_digits=5, decimal_places=2)			# 创建价格字段
    publish = models.CharField(max_length=32)							# 创建出版社字段
    number = models.IntegerField()										# 创建数量字段
    pub_date = models.DateField(auto_now_add=True)						# 创建出版日期字段

>>> python3 manage.py makemigrations app01								# 数据库迁移指令
>>> python3 manage.py migrate app01										# 数据库迁移指令

增加数据

方法一:实例化对象执行对象.save()
	book_obj = models.Book(title='python', price=12.13, number=99, publish='publish_1')
	book_obj.save()

方法二:objects.create()
	book = models.Book.objects.create(title="django", price=1.11, number=9, publish="publish_2")

查询数据

13条表的操作方法

1all():查询所有结果,返回一个QuerySet,类似对象列表
	book_list = models.Book.objects.all()

2filter(**kwargs):查询所有与筛选结果匹配的对象,返回一个QuerySet,类似对象列表
	book_list = models.Book.objects.filter(id=1)

3、get(**kwargs):查询所有与筛选结果匹配的对象,得到的结果必须只有一个,多个或没有就好报错
	book_obj = models.Book.objects.get(id=1)

4、exclude(**kwargs):查询所有与筛选条件不匹配的对象,返回一个QuerySet,类似对象列表
	book_list = models.Book.objects.exclude(id=1)

5、values(*field):返回一个ValueQuerySet(特殊的QuerySet),返回的是一个可迭代的字典序列
	price_list = models.Book.objects.values("price")

6、values_list(*field):与values类似,values返回的字典序列,values_list返回的是元祖序列
	price_list = models.Book.objects.values_list("price")

7、order_by(*field):对查询结果排序
8、reverse(*field):将查询结果反转,只能在排过顺序后使用
9、distinct():对查询结果去重,一般和values或者values_list一起使用
10、count():返回匹配查询的对象数量
11、first():返回第一条记录
12、last():返回最后一条记录
13、exists():查询到数据就返回True,否则返回False

双下划线查询

__lt=num:小于某值
	models.Book.objects.filter(id__lt=3)					# 查询id小于3的值
	
__lte=num:小于等于某值
	models.Book.objects.filter(id__lte=3)					# 查询id小于等于3的值

__gt=num:大于某值
	models.Book.objects.filter(id__gt=3)					# 查询id大于3的值

__gte=num:大于等于某值	
	models.Book.objects.filter(id__gte=3)					# 查询id大于等于3的值

__in=iter:在。。。里面的值
	models.Book.objects.filter(id__in=[1, 2, 3])			# 查询id在list里的值
	
__contains=str:包含某值的值,区分大小写
	models.Book.objects.filter(publish__contains='pub')		# 查询含有'pub'的值,区分大小写
	
__icontains=str:包含某值的值,不区分大小写
	models.Book.objects.filter(publish__icontains='Pub')	# 查找含有'Pub'的值,不区分大小写

__range=[1, 3]:在某范围内的值
	models.Book.objects.filter(id__range=[1,4])				# 查找id在1-4之间的值,顾头顾尾

__startswith=str:开头是某字符的值
	models.Book.objects.filter(publish__startswith='pub')	# 查询开头是'pub'的值
	
__endswith=str:结尾是某字符的值
	models.Book.objects.filter(publish__endswith='pub')		# 查询结尾是'pub'的值

__year=num:某年的值
	models.Book.objects.filter(pub_date__year=2012)			# 查询2012年的值

__month=num:某月的值
	models.Book.objects.filter(pub_date__month=6)			# 查询6月的值

__day=num:某天的值
	models.Book.objects.filter(pub_date__day=12)			# 查询12号的值

__week_day=num:某周的值
	models.Book.objects.filter(pub_date__week_day=3)		# 查询第三周的值

删除数据

方法一:对象.delete()
	book = models.Book.objects.filter(pk=1).first().delete()

方法二:QuerySet.delete()
	book = models.Book.objects.filter(pk=1).delete()	

修改数据

方式一:对象.属性=属性值
	book = models.Book.objects.filter(pk=1).first()
	book.price = 200
	book.save

方法二:QuerySet.update(字段名=数据)
	book = models.Book.objects.filter(pk=1).update(price=200)

表关系

表与表之间的关系分为三种:一对一、一对多、多对多

外键字段

models.ForeignKey(to, to_field, on_delete, db_constraint)
	外键字段,一对多,外键建在多的一方
	to:设置关联的表,当参数为类名时,必须在模型类之后(惰性关系),当参数为字符串形式的类名时,则没有影响
	to_field:设置关联的表的字段
	on_delete:当删除关联表的数据,当前表与其关联行的行为
	db_constraint:是否在数据库中创建外键约束,默认为True

models.OneToOneField(to)
	外键字段,一对一,外键建在常用的一方
	to:设置关联的表,,当参数为类名时,必须在模型类之后(惰性关系),当参数为字符串形式的类名时,则没有影响
	
models.ManyToManyField()
	外键字段,多对多,外键建在常用的一方
	to:设置关联的表,,当参数为类名时,必须在模型类之后(惰性关系),当参数为字符串形式的类名时,则没有影响

class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField(auto_now_add=True)
    publish = models.ForeignKey('Publish')
    author = models.ManyToManyField('Author')

class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)
    phone = models.BigIntegerField()

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    gender_choices = ((1, 'male'), (2, 'female'), (3, 'other'))
    gender = models.CharField(max_length=32, choices=gender_choices)
    details = models.OneToOneField('AuthorDetails')

class AuthorDetails(models.Model):
    msg = models.CharField(max_length=32)

查询数据

正向查询
	对象查找:对象.外键字段.字段
		book_obj = models.Book.objects.all().first()
		book_obj.publish.name
	
	字段查找:外键字段__字段
		book = models.Book.objects.filter(publish__name='pub_1')

反向查询
	对象查找:对象.表名_set
		pub_obj = models.Publish.objects.all().first()
		book_list = pub_obj.book_set.all()
		titles = book_list.values_list("name")
	
	字段查询:表名__字段
		titles = models.Publish.objects.values("book__name")

操作数据

一对多
	获得对象,将对象传给外键字段或将对象的主键id传给外键字段
		models.Publish.objects.create(name='pub_1', addr='苏州', phone='134')					# 先创建被关联表数据
    	pub_obj = models.Publish.objects.filter(pk=1).first()									# 获得被关联表对象
    	book = models.Book.objects.create(name='Python', price=99.99, publish=pub_obj)			# 将对象传给外键字段

多对多
	create():创建一个关联对象,并自动写入数据库,且在第三张关联表中建立双方关系
		models.Author.objects.first().book_set.create(name='P3', price=33.33, publish=pub_obj)	# 先找到作者再为其创建图书并关联到第三张表内
	
	add():把对象添加到第三张表内
		author_list = models.Author.objects.filter(id__lt=3)									# 先查询需要添加的对象
		models.Book.objects.first().author.add(*author_list)									# 再使用add添加关系到第三张表
	
	set():更新某个对象在第三张表中的关联对象,不同于添加add,set相当于重置
		book_obj = models.Book.objects.first().author.set(*[2, 3])
	
	remove():从关联对象中移除指定的对象
		book_obj = models.Book.objects.first().author.remove(3)
	
	clear():从关联对象中移除一切对象
		book_obj = models.Book.objects.first().author.clear()
	ps:clear()和remove()只能在null=True时存在,所有方法都会马上更新数据库。

聚合查询

内置聚合函数:from django.db.models import Avg, Sum, Max, Min, Count

语法:aggregate(别名 = 聚合函数名("属性名称"))
聚合查询返回值是字典,返回的字典中:键的名称默认是(属性名称加上__聚合函数名),值是计算出来的聚合值,可以为其取别名。

res = models.Book.objects.aggregate(Avg("price"))

分组查询

分组查询一般都会用到聚合函数

语法:annotate(别名 = 聚合函数名("属性名称"))
values或values_list在分组函数前面,表示声明以什么字段分组
values或values_list在分组函数后面,表示以当前pk分组,values和values_list表示查询某些字段

res = models.Book.objects.values('name').annotate(Min('price'))

res = models.Book.objects.annotate(Count("name")).values("author__name")

F和Q

F 可以查询引用字段,比较同一个model实例两个不同字段的值
Q 可以用于条件判断,一般用于复杂的判断语句
引用:from django.db.models import F, Q
语法:F(“字段名称”)
语法:Q(条件判断)

逻辑符号 &:与,|:或,~:非,优先级从高到低:~ & |

from django.db.models import F, Q

res = models.Book.objects.filter(price__gt=F('number'))

res = models.Book.objects.filter(Q(price__gt=10)|Q(number__lt=10))

其他操作

执行原生SQL
	extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)

开启事务
	from django.db import transaction
	 with transaction.atomic():
	 	事务内容

优化查询数据库
	select_related:表之间进行join连表操作,一次性获取关联数据
		主要针对一对多和一对一关系优化
		使用sql的join语句进行优化,通过减少sql查询的次数来进行优化、提高性能
	
	prefetch_related:使其执行多次sql查询在python代码中实现连表操作
		主要针对多对多和一对多关系优化
		分别查询每个表,然后用python处理他们的关系
		
批量插入
	bulk_create(obj_list)
	models.Book.objects.bulk_create(obj_list)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值