模型层
单表及测试环境准备
测试脚本
"""
当你只是想要测试 django 中的一个 py 文件时 可以不用书写前后端交互的形式,而是直接写一个测试脚本
"""
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoProject.settings")
import django
django.setup()
from app01 import models
查看内部 sql 语句
queryset 对象才能点击 query 查询内部的 sql 语句
res = models.USER605.objects.values_list("name")
print(res.query)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
必知必会13条
神奇的双下划线查询
外键的增删查改
一对多(一对一)外键
一对多外键
models.book606.objects.create(title="三国演义", price=123.12, publish_id=1)
pushlish_obj = models.publish606.objects.filter(pk=1).first()
models.book606.objects.create(title="奥特曼", price=111.11, publish=pushlish_obj)
models.publish606.objects.filter(pk=1).delete()
models.book606.objects.filter(pk=1).update(publish_id=2)
obj = models.publish606.objects.filter(pk=2).first()
models.book606.objects.filter(pk=1).update(publish=obj)
多对多外键
多对多 增删改查 就是在操作第三张表
author_obj = models.author606.objects.filter(pk=2).first()
print(author_obj.author2book)
author_obj.author2book.add(1)
author_obj.author2book.add(2, 3)
book_obj = models.book606.objects.filter(pk=1).first()
book_obj1 = models.book606.objects.filter(pk=2).first()
book_obj2 = models.book606.objects.filter(pk=3).first()
author_obj.author2book.add(book_obj, book_obj1, book_obj2)
author_obj = models.author606.objects.filter(pk=1).first()
author_obj.author2book.remove(2, 3)
author_obj = models.author606.objects.filter(pk=2).first()
author_obj.author2book.set([1, 3])
clear 内部什么都不要传入
author_obj = models.author606.objects.filter(pk=2).first()
author_obj.author2book.clear()
正反向的概念
看外键字段在哪里。
外键字段在A,A查B 就是正向
外键字段在B,A查B 就是反向
'''
正向查询按字段
反向查询按表名小写
_set
...
'''
多表查询
子查询(基于对象的跨表查询)
基于对象的跨表查询
book_obj = models.book606.objects.filter(pk=1).first()
res = book_obj.publish
print(res.name)
print(res.addr)
author_obj = models.author606.objects.filter(pk=1).first()
res = author_obj.author2book.all()
print(res)
author_obj = models.author606.objects.filter(name="jason").first()
res = author_obj.authordetail
print(res.phone)
publish_obj = models.publish606.objects.filter(pk=1).first()
res = publish_obj.book606_set.all()
print(res.values("title"))
book_obj = models.book606.objects.filter(pk=4).first()
res = book_obj.author606_set.all()
print(res.values("name"))
author_detail_obj = models.authordetail606.objects.filter(pk=1).first()
res = author_detail_obj.author606
print(res.name)
联表查询(基于双下划线的跨表查询)
基于双下划线的跨表查询
res = models.author606.objects.filter(name="jason").values("authordetail__phone")
print(res)
res = models.book606.objects.filter(pk=1).values("title","publish__name", "publish__addr")
print(res)
res = models.author606.objects.filter(pk=1).values("author2book__title")
print(res)
res = models.authordetail606.objects.filter(author606__name="jason")
res = models.authordetail606.objects.filter(author606__name="jason").values("phone","author606__name")
print(res)
res = models.publish606.objects.filter(book606__id=1).values("book606__title", "addr")
print(res)
res = models.book606.objects.filter(author606__id=1).values("title", "author606__name")
print(res)
res = models.book606.objects.filter(pk=1).values("author606__authordetail__phone")
print(res)
聚合查询
from django.db.models import Sum,Count,Min,Max,Avg
res = models.book606.objects.aggregate(Avg("price"))
print(res)
分组查询
from django.db.models import Sum, Count, Min, Max, Avg
res = models.book606.objects.annotate(author_num=Count('author606')).values("title","author_num")
print(res)
res = models.publish606.objects.annotate(book_price=(Min('book606__price'))).values("name", "book_price")
print(res)
res = models.book606.objects.annotate(author_num=Count("author606")).filter(author_num__gte=2).values("title")
print(res)
res = models.author606.objects.annotate(total_price=Sum("author2book__price")).values("name", "total_price")
print(res)
models.book606.objects.values("price").annotate()
F查询
from django.db.models import F
res = models.book606.objects.filter(maichu__gt=F("kucun")).values("title")
print(res)
models.book606.objects.update(price=F("price")+500)
from django.db.models.functions import Concat
from django.db.models import Value
models.book606.objects.update(title=Concat(F("title"), Value("爆款")))
Q查询
from django.db.models import Q
res = models.book606.objects.filter(Q(price__lt=600), Q(maichu__gt=100)).values("title")
res = models.book606.objects.filter(Q(price__lt=600)|Q(maichu__gt=100)).values("title")
print(res)
q = Q()
q.children.append(("maichu__gt", 100))
q.children.append(("price__lt", 600))
res = models.book606.objects.filter(q).values("title")
print(res)
django中开启事务
"""
事务
ACID
原子性
不可分割的最小单位
一致性
跟原子性相辅相成
隔离性
事务之间互相不干扰
持久性
事务一旦确认永久生效
事务的回滚
rollback
事务的确认
commit
"""
from django.db import transaction
with transaction.atomic():
print('执行其他操作')
orm 中常用字段以及参数
AutoField
主键字段 primary_key = True
CharField 对应 varchar
verbase_name 字段的注释
max_length 长度
IntergeField int
BigIntergeField bigint
DecimalField
max_disgits 总位数
decimal_places 小数位数
EmailField varcahr(254)
DateField date
DateTimeField datetime
auto_now 修改数据时自动更新时间
auto_now_add 创建数据时填入时间,之后就不会自动修改
BooleanField 布尔值类型
该字段传入 布尔值(True/False),数据库里面存 0/1
TextField 文本类型
可以存大段内容(文章、博客...)没有字数限制
FileField
upload_to = "/data" 给该字段传入一个文件对象,会自动将文件保存到 /data 目录下,然后将文件路径存到数据库中
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
unique = True
ForeignKey(unique=True) === OneToOneField()
to_field
设置要关联的表的字段 默认不写就是关联主键
on_delete
级联删除,当删除关联表中的数据时,当前表与其关联的行的行为。
数据库查询优化
only 与 defer
select_related 与 prefetch_related
"""
orm 语句的特点
惰性查询
如果仅仅书写 orm 语句,后面没有用到查询的数据,该orm语句不会执行
"""
res = models.book606.objects.values("title")
for i in res:
print(i.get("title"))
res = models.book606.objects.only("title")
for i in res:
print(i.title)
print(i.price)
res = models.book606.objects.defer("title")
for i in res:
print(i.price)
res = models.book606.objects.all()
for i in res:
print(i.publish.name)
res = models.book606.objects.select_related("publish")
for i in res:
print(i.publish.name)
res = models.book606.objects.prefetch_related("publish")
for i in res:
print(i.publish.name)