模型层(ORM操作)&数据的增删改查
参考文章:https://www.cnblogs.com/liuqingzheng/articles/9472723.html
https://www.cnblogs.com/Dominic-Ji/p/9203990.html
单独操作模型表步骤
在项目路径下新建一个test.py
编辑test.py
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day65onesearch.settings")
import django
django.setup()
from app01 import models
os.environ.setdefault(“DJANGO_SETTINGS_MODULE”, “day65onesearch.settings”) 需要从manage.py
拷贝过来。
新增
创app01下的models.py中创建模型:
from django.db import models
# Create your models here.
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish_date = models.DateField('auto_now_add')
publish = models.CharField(max_length=32)
author = models.CharField(max_length=32)
增加
create (属性值=‘xxx’)
create(属性值 =外键对象)
一对多:外键的处理
models.Book.objects.create(publish_id=2)
models.Book.objects.create(publish=publish_obj)
多对多
对象.属性的时候,已经跨到了author表中,此时就可以进行add操作了
方法一:
book_obj = models.Book.objects.filter(name=‘书名’).first()
book_obj.authors.add(1)
方法二:
book_obj = models.Book.objects.filter(name=‘书名’).first()
author_obj =models.Author.objects.filter(id=3).first #author对象
book_obj.authors.add(author_obj)
方法三:queryset方式添加
author_queryset = models.Author.objects.all() #queryset对象
book_obj.authors.add(*author_queryset ) #把queryset对象打散,本质还是传的对象
查询
all() : QuerySet
filter: QuerySet
get():获得对象,但是对象不存在时候会报错
跨表查询
基于对象的查询
正向:字段本表中有—> 按字段
反向:字段在别的表中—> 按 表明小写
正向查询
例:![在这里插入图片描述](https://img-blog.csdnimg.cn/20190418190448427.pn
注意:一对一或者一对多的时候,直接.字段
可以直接用对象.属性,但是一对多的时候,必须在后面加上all,否则获得是就是一个 None,因为直接查系统不知道你要获得哪个数据。
加上all()后:
反向查询
一对多 或 多对多
对象.表名小写_set.
凡是查询到的一方为多的,都需要在后面加all(返回queryset对象),若不加则返回一个none对象;一方为一的,可以直接.属性
一对一
对象.表名小写.属性
基于QuerySet(双下划线)的查询
正反查询:正向按字段,反向按表名,中间用__链接。
正向查询
注意,用这种方式取到的结果,queryset对象中的键值对的键名为 values 中设定的值
反向查询
修改
注释:对象obj = models.Book.objects.all().first()
QuerySet.update(属性 = ‘xxx’)
models.Book.objects.update(name='书名')
models.Book.objects.update(publish=publish_obj)
对象.属性 = “xxx”
对象.save()
多对多
book_obj = models.book.objects.filter(pk=1).first()
book_obj.author.set([1,]) #设置中间表 set方式是先清空再添加,set的参数必须是可迭代对象
删除
QuerySet.delete()
多对多
book_obj = models.book.objects.filter(pk=1).first()
book_obj.authors.remove(2) #删除的关联表数据 ,支持传多个参数
book_obj.authors.clear() #一次性清空
常用查询方法
返回QuerySet对象的方法有:
all()
filter()
exclude()
order_by():
reverse():
distinct():
特殊的QuerySet:
values() 返回一个可迭代的字典序列
values_list() 返回一个可迭代的元祖序列
返回具体对象的:
get()
first()
last()
返回布尔值的方法有:
exists()
返回数字的方法有
count()
详细介绍
<1> all(): 查询所有结果
<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
<3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
<4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
<5> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
<6> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
<7> order_by(*field): 对查询结果排序
<8> reverse(): 对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
<9> distinct(): 从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)
<10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。
<11> first(): 返回第一条记录
<12> last(): 返回最后一条记录
<13> exists(): 如果QuerySet包含数据,就返回True,否则返回False
聚合查询:
from django.db.models import Avg, Sum, Max ,Min , Count
#对这个价格取平均值
res = models.Book.objects.all().aggregate(Avg('price'))
#对这个价格取总和
res = models.Book.objects.all().aggregate(Sum('price'))
返回值是一个字典
分组查询
统计每一本书的个数
注:分组查询需要,把数据库的严格模式取消,否则会报错。
res = models.Book.objects.all().annotate(author_num=Count('authors'))
F与Q查询
F:查询,查询的左右条件两边都来自于数据库而非手动输入
例1:
from django.db.models import F,Q
#查询卖出数大于库存数的书籍
res = models.Book.objects.filter(maichu__gt=F(‘kucun’)).values(‘name’)
print(res)
例2:将每个商品的价格提高50元。
res = models.Book.objects.update(price=F('price')+50)
Q查询能够将filter内部默认的and关系转换成 与或非
例1:
查询数据名字是金瓶梅或
者价格是72.22的书籍
或
res = models.Book.objects.filter(Q(name =‘金瓶梅’)|Q(price=‘72.22’))
print(res)
res = models.Book.objects.filter(Q(name =‘金瓶梅’)|Q(price=‘72.22’)).values(‘name’)
print(res)
非:
与:&