1.查询主键为1的书籍对应的出版社名称和书名
models.Publish.objects.filter(book__pk=1).values('name','book__title')
2.查询主键为3的书籍对应的作者及书名
models.Author.objects.filter(book__pk=3).values('name','book__title')
3.查询jason的作者电话号码和地址
models.AuthorDetail.objects.filter(author__name='jason').values('phone', 'addr')
4.查询南方出版社出版的书籍的名称及价格
models.Book.objects.filter(publish__name='南方出版社').values('title', 'price')
5.查询jason写过的书名和日期
models.Book.objects.filter(authors__name='jason').values('title', 'publish_date')
6.查询主键为1的书籍对应的作者电话号码
models.Author.objects.filter(book__pk=1).values('author_detail__phone')
models.AuthorDetail.objects.filter(author__book__pk=1).values('phone')
1.首先第一步需要导入模块
from django.db.models import Max, Min, Sum, Avg, Count
2.没分组之前聚合查询需要使用关键字aggregate
models.Book.objects.aggregate(Max('price'), Min('price'),Count('pk'))
# 第一步:在终端进入mysql,输入以下指令
set global sql_mode = 'STRICT_TRANS_TABLES'
# 第二步:退出mysql
# 第三步:重新进入mysql即可
models.Book.objects.annotate()
案例1:统计每一本书的作者个数
models.Book.objects.annotate(author_num=Count(authors__pk)).values('author_num')
按照annotate前面values括号中的字段分组
models.Book.objects.values('title').annatate()
案例2:统计每一个出版社的数的数量
models.Book.objects.values('publish_id').annotate(book_num=Count('pk')).values('book_num')
案例3:统计出每个出版社卖的最便宜的书的价格
models.Publish.objects.annotate(min_price=Min(book__price)).values('name','min_price')
案例4:统计不止一个作者的书
models.Book.objects.annotate(author_num=Count('authors__pk')).filter(author_num__gt=1).values('title', 'author_num')
案例5:查询各个作者出的书的总价格
models.Author.objects.annotate(sum_price=Sum(book__price)).values('name','sum_price')
1.F查询条件不是自定义的,而是来自于表中的字段
首先需要导入F模块
from django.db.models import F
案例1:查询库存数大于卖出数的书籍
models.Book.objects.filter(stock_num__gt=F('sale_num'))
案例2:将所有的书籍价格上涨1000块
models.Book.objects.update(price=F('price')+1000)
案例3:将主键为1的书籍名称加上爆款后缀
from django.db.models.functions import Concat
from django.db.models import Value
models.Book.objects.filter(pk=1).update(title=Concat(F('title'), Value('爆款')))
1.默认是and关系
models.Book.objects.filter(pk=1, publish_id=3)
2.逗号分割还是and关系
models.Book.objects.filter(Q(pk=1), Q(piblish_id=3))
3…管道符是or的关系
models.Book.objects.filter(Q(pk=1) | Q(publish_id=3))
4.波浪号是not关系
models.Book.objects.filter(~Q(pk=1) | Q(publish_id=3))
5.Q查询可以可以将查询条件的字段改为字符串形式
q_obj = Q()
q_obj.connector = 'or' # q对象默认的多个条件是and关系
q_obj.children.append(('pk',1))
q_obj.children.append(('publish_id',3))
res = models.Book.objects.filter(q_obj)
print(res)
res = models.Book.objects.only('title', 'price')
for obj in res:
print(obj.title)
print(obj.price)
print(obj.publish_time)
only会将括号内填写的字段封装成一个个的数据对象,对象在点击的时候不会再走数据库查询,但是对象点括号中没有的字段的时候,每次都会走数据库
总结:对象点only括号内有的字段不会走数据库,点括号中没有的字段会走数据库
res = models.Book.objects.defer('title', 'price')
for obj in res:
print(obj.title)
print(obj.price)
print(obj.publish_time)
总结:对象点defer括号内有的字段会走数据库,点括号中没有的字段不会走数据库
res = models.Book.objects.select_related('authors')
for obj in res:
print(obj.publish.name)
总结:
res = models.Book.objects.prefetch_related('publish')
for obj in res:
print(obj.publish.name)
总结:
from django.db import transaction
try:
with transaction.atomic():
pass # 多条ORM语句
except Exception as e:
print(e)
字段 | 功能 |
---|---|
AutoField() | int类型且自增,必须填入参数 primary_key=True |
CharField() | 主要存储字符串的数据类型 |
IntegerField() | 存储整型数据 |
BigIntegerField() | 大整型,只要用于存储整型的数据 |
DateField() | 主要存储日期类型的数据类型,年月日 |
DateTimeField() | 主要存储日期类型的数据类型,时分秒 |
DecimalField() | 表示固定精度的十进制数的字段。它有两个必须的参数:max_digits:数字允许的最大位数decimal_places:小数的最大位数 |
EmailField() | 邮件格式的数据 |
BooleanField() | 传布尔值存数字0或1 |
TextField() | 存储大段文本 |
FileField() | 存储文件数据 自动找指定位置存储 字段存具体路径 |
ForeignKey() | 外键字段 |
OneToOneField() | 一对一外键字段 |
ManyToManyField() | 多对多外键字段 |
class MyCharField(models.Field):
def __init__(self, max_length, *args, **kwargs):
self.max_length = max_length
super().__init__(max_length=max_length, *args, **kwargs)
def db_type(self, connection):
return 'char(%s)' % self.max_length
info = MyCharField(max_length=32)
字段参数 | 说明 |
---|---|
max_length | CharField必须要设置该参数,不然会报错 |
verboses_name | 相当于注释 |
auto_now | 修改一次就重新记录一次此次修改的事件 |
auto_now_add | 只有创建的时候记录,以后不会改变 |
null | 用于表示某个字段可以为空。设置方式:null = True |
default | 为该字段的默认值,设置方式:default = ‘默认值’ |
max_digits | 数字允许的最大位数 |
decimal_places | 小数的最大位数 |
unique=True | 用于表示该字段值在此表中必须是唯一的,建立唯一索引,设置方式:unique = True |
db_index=True | 将该字段设置为索引,设置方式:db_index = True |
to | 绑定外键字段对应的表 |
to_field | 指定想要绑定的外键字段 |
related_name | 给外键字段起别名 |
当字段数据的可能性可以完全列举出来的时候 应该考虑使用该参数
class UserInfo(models.Model):
username = models.CharField(max_length=32)
gender_choice = (
(1, '男性'),
(2, '女性'),
(3, '其他'),
)
gender = models.IntegerField(choices=gender_choice)
userinfo_obj.get_gender_display()
参数 | 功能 |
---|---|
models.CASCADE | 级联操作,当主表中被连接的一条数据删除时,从表中所有与之关联的数据同时被删除 |
models.SET_NULL | 当主表中的一行数据删除时,从表中所有与之关联的数据的相关字段设置为null,此时注意定义外键时,这个字段必须可以允许为空 |
models.PROTECT | 当主表中的一行数据删除时,由于从表中相关字段是受保护的外键,所以都不允许删除 |
models.SET_DEFAULT | 当主表中的一行数据删除时,从表中所有相关的数据的关联字段设置为默认值,此时注意定义外键时,这个外键字段应该有一个默认值 |
models.SET() | 当主表中的一条数据删除时,从表中所有的关联数据字段设置为SET()中设置的值,与models.SET_DEFAULT相似,只不过此时从表中的相关字段不需要设置default参数 |
models.DO_NOTHING | 什么都不做,一切都看数据库级别的约束,注数据库级别的默认约束为RESTRICT,这个约束与django中的models.PROTECT相似 |
authors = models.ManyTOManyField(to='Author')
class Book(models.Model):
pass
class Author(models.Model):
pass
class Book2Author(models.Model):
book_id = models.ForeignKey(to="Book")
author_id = models.ForeignKey(to="Author")
class Book(models.Model):
authors = models.ManyToManyField(to='Author',
through='Book2Author'
through_fields=('book_id','author_id')
)
class Author(models.Model):
pass
class Book2Author(models.Model):
book_id = models.ForeignKey(to="Book")
author_id = models.ForeignKey(to="Author")