day07 ORM中常用字段和参数
今日内容
- 常用字段
- 关联字段
- 测试环境准备
- 查询关键字
- 查看ORM内部SQL语句
- 神奇的双下划线查询
- 多表查询前提准备
常用字段
字段类型
AutoField
int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
IntegerField
一个整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,)
CharField
字符类型,必须提供max_length参数, max_length表示字符长度。
DateField
日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
DateTimeField
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例
#应用上面自定义的char类型
class Class(models.Model):
id=models.AutoField(primary_key=True)
title=models.CharField(max_length=32)
class_name=FixCharField(max_length=16)
gender_choice=((1,'男'),(2,'女'),(3,'保密'))
gender=models.SmallIntegerField(choices=gender_choice,default=3)
publish_time = models.DateField(auto_now=True,auto_now_add=True)
字段参数
null
用于表示某个字段可以为空。
unique
如果设置为unique=True 则该字段在此表中必须是唯一的 。
db_index
如果db_index=True 则代表着为此字段设置索引。
default
为该字段设置默认值。
DateField和DateTimeField # 年月日时分秒
auto_now_add
配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。
auto_now
配置上auto_now=True,每次更新数据记录的时候会更新该字段。
关系字段
ForeignKey:外键字段
# ForeignKey
外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多'中'多'的一方。
ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系。
# 字段参数
to
设置要关联的表
to_field
设置要关联的表的字段
on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。
models.CASCADE
删除关联数据,与之关联也删除
db_constraint
是否在数据库中创建外键约束,默认为True。
def func():
return 10
class MyModel(models.Model):
user = models.ForeignKey(
to="User",
to_field="id",
on_delete=models.SET(func)
)
OneToOneField:外键字段
# 一对一字段。
通常一对一字段用来扩展已有字段。(通俗的说就是一个人的所有信息不是放在一张表里面的,简单的信息一张表,隐私的信息另一张表,之间通过一对一外键关联)
# 字段参数
to
设置要关联的表。
to_field
设置要关联的字段。
on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。(参考上面的例子)
ORM必知必会13条
创建表
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2) # 浮点型
publish_time = models.DateField(auto_now=True,auto_now_add=True) # 年月日
# auto_now :每次修改数据会自动更新当前时间
# auto_now_add :仅在创建时自动更新时间,之后不是人为的修改,则时间一直不变
'''django自带的sqlite数据库功能非常的少 并且对日期格式不兼容'''
1.MySQL配置
2.数据库迁移命令
3.ORM查询关键字
测试环境准备
# 测试环境有两种
1.python console(pycharm下方自带)
2.py文件形式(参考manage.py前四行) # 随便创建一个py文件,添加一下几行代码
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "py_dj7.settings")
import django
django.setup()
# 在该代码的下方才可以正常测试django文件
常用字段
# 只要是QuerySet对象,就可以无限制的调用QuerySet对象方法
1、all():查询所有结果
print(models.Book.objects.all())
'''QuerySet支持正数索引,不支持负数索引'''
2、filter(): 它包含了与所给筛选条件相匹配的对象 # 支持索引取值
print(models.Book.objects.filter(pk=1)) # fiter不加条件,也是查找所有
print(models.Book.objects.filter(pk=1).first()) # 拿去第一个数值
<QuerySet [<Book: 圣王>]> # QuerySet 列表套数据对象
'''
ilter可以写多个条件,并且中间用逗号当成and关系
pk相当于主键id,不在乎是id、uid等不同名称
可以根据索引取值,推荐使用first()
'''
3、first():返回第一个数据
print(models.Book.objects.filter(pk=1).first()) # 圣王
4、last():返回最后一个数据
print(models.Book.objects.all().last()) # 永生
4、 values(): values可以指定查询的字段,结果QuerySet 列表套字段,是一个可迭代的字典序列
print(models.Book.objects.values('title'))
<QuerySet [{'title': '圣王'}, {'title': '阳神'}, {'title': '遮天'}, {'title': '永生'}]>
'''
支持索引取值first()和last()、[0],但是不支持负数索引
'''
5、values_list():它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
print(models.Book.objects.values_list('title','price').first())
('圣王', Decimal('111.11'))
6、get():返回给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象不存在会抛出错误。
res = models.Book.objects.get(pk=1)
print(res,res.publish_time,res.price) # 圣王 2021-11-01 111.11
7、exclude(): 取反
print(models.Book.objects.exclude(pk=1))
8、order_by():排序(从小到大)
print(models.Book.objects.order_by('price'))
9、reverse():反转,配合order_by
print(models.Book.objects.order_by('price').reverse())
10、distinct():去重
res = models.Book.objects.all().values('title','price')
print(res.distinct())
<QuerySet [<Book: 圣王>, <Book: 阳神>, <Book: 遮天>, <Book: 永生>, <Book: 圣王>]>
'''注意:不加values会有id条件不同,索取去重的前提是把id过滤掉'''
11、count():计数
print(models.Book.objects.count()) # 4个
12、exisit():如果QuerySet包含数据,就返回True,否则返回False
print(models.Book.objects.filter(pk=10).exists()) # False
13、create():创建
14、update():修改
15、delete():删除
16、obj.save():保存
如何查看SQL语句
1、如果当前对象是queryset那么可以直接点query查找该对象内部SQL语句
res = models.Book.objects.all()
print(res.query)
2、settings.py配置文件(只要执行orm语句都会自动打印SQL语句)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
神奇的双下划线查询
# 双下划线查询:
__gt:大于
__lt:小于
__gte:大于等于
__lte:小于等于
__in:在
__range:范围
__contains:包含
__startswith:以什么开头
__endswith:以什么结尾
_time__year:年
_time__month:月
案例1:查询书籍价格大于100的书
print(models.Book.objects.filter(price__gt=100)) # __gt:大于
案例2:查询书籍价格小于100的书
print(models.Book.objects.filter(price__lt=100)) # __lt:小于
案例3:查询书籍价格大于等于100的书
print(models.Book.objects.filter(price__gte=100)) # __gte:大于等于
案例4:查询书籍价格小于等于800的书籍
print(models.Book.objects.filter(price__lte=100)) # __lte:小于等于
案例5:查询书籍价格是92.12 或者35.60 或者111.11
print(models.Book.objects.filter(price__in=["92.12","35.60","111.11"])) #__in:在
案例6:查询书籍价格在100到200之间的书籍
print(models.Book.objects.filter(price__range=(100,200))) # __range:范围
案例7:查询书籍名称中包含字母p的书(区分大小写)
print(models.Book.objects.filter(title__contains='p')) # __contains:包含
案例8:查询书籍是否以...开头 ...结尾
print(models.Book.objects.filter(title__startswith='a')) # __startswith:以什么开头
print(models.Book.objects.filter(title__endswith='a')) # __endswith:以什么结尾
案例9:查询出版日期是2021的书(常用)
print(models.Book.objects.filter(publish_time__year=2021)) # _time__year:年
print(models.Book.objects.filter(publish_time__month=11)) # _time__month:月