### 11.9 ORM的字段和参数
```python
AutoField 主键
IntegerField 整数
CharField 字符串
BoolleanField 布尔值
DateTimeField DateField 日期时间
auto_now_add=True #新增数据的时候回自动保存当前的时间
auto_now=True #新增、修改数据的时候回自动保存当前的时间
DecimalField 十进制的小数
max_digits 小数总长度
decimal_place 小数长度
```
参数:
- null 数据库中字段是否可以为空
- blank=True form表当填写的时候可以为空
- default 字段的默认值
- db_index 创建索引
- unipue 唯一
- choices=((0,'女'),(1,'男')) 可填写的内容和提示
表的参数
```python
#是放在app01中models中,class Xxx中的一个子类,规定表的属性
class Meta:
db_table = "person" #表名
verbose_name = "个人信息"
verbose_name_plural = "个人信息"
index_together = [
("name","age"), # 应该为两个存在的字段
]
unique_together = (("name","age",)) #应该为两个存在的字段
```
#### 11.9.1 必知必会13条
ORM的13条基本命令:
- 获取所有数据------->对象列表
- ret = models.Person.objects.all()
- 获取一个满足条件的数据
- ret = models.Person.objects.aget()
- 获取满足条件的所有数据
- ret = models.Person.objects.filter()
- 获取不满足条件的所有数据
- ret = models.Person.objects.exclude()
- 拿到对象的所有字段和字段的值
- ret = models.Person.objects.values()
- 拿到对象指定的字段和字段的值
- ret = models.Person.objects.values('字段')
- 排序
- ret = models.Person.objects.all().order_by('id')
- 反向排序
- ret = models.Person.objects.all().reverse()
- 去重
- ret = models.Person.objects.values('age').distinct()
- 计数
- ret = models.Person.objects.all().count()
- 取第一个元素 没有元素就是None
- ret = models.Person.objects.filter(pk=1).values().first()
- 取最后一个元素
- ret = models.Person.objects.filter(pk=1).values().last()
- 查询的数据是否存在
- ret = models.Person.objects.filter(pk=1).exists()
#### 11.9.2 单表的双下划线
- ret = models.Person.objects.filter(pk__gt=1) gt greater than 大于
- ret = models.Person.objects.filter(pk__lt=1) lt less than 小于
- ret = models.Person.objects.filter(pk__gte=1) gte greater than equal 大于等于
- ret = models.Person.objects.filter(pk__lte=1) gte less than equal 小于等于
- ret = models.Person.objects.filter(pk__range=[2,3]) #范围 包括头和尾
- ret = models.Person.objects.filter(pk__in=[2,3,100]) 成员判断
- ret = models.Person.objects.filter(name__contains='A') 判断是否有A的内容
- ret = models.Person.objects.filter(name__icontains='A') 忽略大小写
- ret = models.Person.objects.filter(name__startswith='A') 以什么开头
- ret = models.Person.objects.filter(name__istartswith='A') 忽略大小写
- ret = models.Person.objects.filter(name__endswith='A')
- ret = models.Person.objects.filter(name__iendswith='A')
#### 11.9.3 外键操作(查询)
##### 11.9.3.0正向查询和反向查询
基于对象的查询(查菊花怪大战桃花侠)
正向查询:
book_obj = models.Book.objects.get(title='菊花怪大战桃花侠') #查询书籍
反向查询
pub_obj = models.Publisher.objects.get(pk=1)
ret = pub_obj.book_set.all() 类名小写+_set 没有指定related_name
ret = pub_obj.books.all() 指定related_name='books'
基于字段的查询
ret = models.Book.objects.filter(title='菊花怪大战桃花侠')
查南海出版社的书
ret = models.Book.objects.filter(pub__name = '南海出版社')
查询初版桃花怪大战菊花侠的出版社
ret = models.Publisher.objects.filter(books__title='菊花怪大战桃花侠') #指定了related_name="books"
ret = models.Publisher.objects.filter(book__title='菊花怪大战桃花侠') #没有related_name 用类名的小写
##### 11.9.3.1多对多的操作:
方法一:
book_obj = models.Book.objects.filter(title="桃花侠大战菊花怪").first()
不指定related_name
print(book_obj.author_set) -----> 关系管理对象
print(book_obj.author_set.all())
指定related_name = 'authors'
print(book_obj.authors) -----> 关系管理对象
print(book_obj.authors.all())
方法二:
不指定related_name
ret = models.Book.objects.filter(anthor__name='liujia')
指定related_name = 'authors'
ret = models.Book.objects.filter(anthors__name='liujia')
指定related_query_name = 'xxx'
ret = models.Book.objects.filter(xxx__name='liujia')
关系管理对象的方法:
ret = models.Author.objects.get(pk=1)
- ret.book.all() 所关联的所有的对象
- ret.book.set([id,id]或者[对象,对象]) 设置多对多的关系
- ret.book.set(4,5)
- ret.book.set(*models.Book.objects.filter(pk__in=[1,2,3]))
- ret.book.add([id,id]或者[对象,对象]) 添加多对多的关系
- ret.book.add(4,5)
- ret.book.add(*models.Book.objects.filter(pk__in=[4,5]))
- ret.book.remove([id,id]或者[对象,对象]) 删除所有的多对多关系
- ret.book.remove(4,5)
- ret.book.remove(*models.Book.objects.filter(pk__in=[4,5]))
- ret.book.clear() 删除所有的多对多关系
- obj = ret.book.create(title='我是达奚栓',pub_id= 1)
##### 11.9.3.2 聚合和分组 F和Q
聚合和分组
```python
from app01 import models
from django.db.models import Max,Min,Avg,Sum,Count
ret = models.Book.objects.filter(pk__gt=3).aggregate(Max('price'),avg=Avg('price'))
print(ret)
#分组 统计每一本书的作者个数
ret = models.Book.objects.annotate(count=Count('author')) #annotate 注释的意思
#统计出每个出版社的最片之一的书的价格
#方式一
ret = models.Publisher.objects.annotate(Min('book__price')).values()
#方式二
ret = models.Book.objects.values('pub_id').annotate(min=Min('price'))
```
F和Q
```python
from django.db.models import F
#比较两个字段的值
ret = models.Book.objects.filter(sale_gt=F('kucun'))
#只更新sale字段
models.Book.objects.all().update(sale=100)
#取某个字段的值进行操作
models.Book.objects.all().update(sale=F('sale')*2+10)
```
```python
from django.db.models import Q
#注释:|或 &与 ~非
ret = models.Book.objects.filter(Q(Q(pk__gt=3)|Q(pk__lt=2))&Q(price__gt=80))
```
事务
```python
from django.db import transaction
try:
with transaction.atomic():
#进行一系列的ORM操作
models.Publisher.objects.create(name = 'ssss')
except Exception as e :
print(e)
```
###