如果想要在django项目中运行py文件,就要在新建的py文件下添加:
import os if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled4.settings") import django django.setup()
这样就可以在这样就可以在django项目中运行py文件了。
先在models写自己的类,然后再py文件中引入就可以了。
我们在models创建这么几个类:
from django.db import models # Create your models here. class Person(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() birth = models.DateField(auto_now=True) class Publisher(models.Model): name = models.CharField(max_length=32) class Book(models.Model): title = models.CharField(max_length=32) publisher = models.ForeignKey(to='Publisher') class Author(models.Model): name = models.CharField(max_length=32) books = models.ManyToManyField(to='Book')
接下来我们来写py文件
必知必会13条:
#all 查询所有数据 Queryset ret = models.Person.objects.all() # print(ret)
#get 获取一个对象,如果查询没有或者多个 就报错 ret1 = models.Person.objects.get(id = 1) ret2 = models.Person.objects.get(name='阿瑟东') # print(ret1) # print(ret2)
#filter 查询所有满足条件的对象 ——》QuerySet ret = models.Person.objects.filter(id=1) ret = models.Person.objects.filter(name='阿瑟东')
# exclude 查询所有不满足条件的对象 ——》QuerySet ret = models.Person.objects.exclude(id=1) # print(ret)
# values 不写参数 取对象的所有字段数据 指定参数 取对象指定字段的参数 ——》QuerySet 元素是字典 ret = models.Person.objects.values() ret = models.Person.objects.values('id','name','age') # print(ret) # for i in ret: # print(i)
# values_list # 不写参数 取对象的所有字段数据 元组形式 # 指定参数 取对象指定字段的参数 ——》QuerySet 按照你参数顺序排序 ret = models.Person.objects.values_list() ret = models.Person.objects.values_list('name','id') # print(ret) # for i in ret : # print(i)
# order_by 按照指定字段排序 默认升序 加负号降序 # 可以多字段排序 ret = models.Person.objects.all().order_by('age','-id') # print(ret) # for i in ret: # print(i,i.id,i.age)
# reverse 对已经排序的QuerySet进行反向排序 # 用了order_by 要不用了ordering ret = models.Person.objects.all().order_by().reverse() # print(ret) ret = models.Person.objects.all().reverse()#没有效果 # print(ret)
# distinct 去重 ret = models.Person.objects.values('name','age').distinct() # print(ret)
# count() 计数 对QuerySet的对象进行计数 ret = models.Person.objects.filter(name='和尚').count() # print(ret)
#first 返回第一条记录 ret = models.Person.objects.first() # print(ret)
#last 返回最后一条记录 ret = models.Person.objects.last() # print(ret)
# exists() 如果QuerySet包含数据,就返回True,否则返回False ret = models.Person.objects.filter(id=5).exists() print(ret)
小结一下:
返回QuerySet列表的方法:
1. all()
2. filter()
3. exclude()
4. values()
5. values_list()
6. reverse()
7. distinct()
8. order_by()
返回具体对象的方法:
1. get()
2. first()
3. last()
返回数字的方法:
1. count()
返回布尔值:
1. exists()
单表查询之神奇的双下划线:
# 获取大于1小于3的值 ret = models.Person.objects.filter(id__gt=1,id__lt=3) #大于1 ret1 = models.Person.objects.filter(id__gt=1) #小于3 ret2 = models.Person.objects.filter(id__lt=3) # print(ret1) # print(ret2) # 获取id等于1,3,5,7,9的值,如果没有,就不获取。 ret = models.Person.objects.filter(id__in=[1,3,5,7,9]) # print(ret) #获取id不等于1,3,5的值 ret = models.Person.objects.exclude(id__in=[1,3,5]) # print(ret) #获取名字中包含‘阿’的值 ret = models.Person.objects.filter(name__contains='阿') # print(ret) #icontains对英文的大小写不敏感。 获取名字中包含as的值 ret = models.Person.objects.filter(name__icontains='as') # print(ret) #获取id范围值为1到3的值 ret = models.Person.objects.filter(id__range=[1,3]) # print(ret) #startswith endswith istartwith iendswith ret1 = models.Person.objects.filter(name__startswith='阿') ret2 = models.Person.objects.filter(name__istartswith='阿') ret3= models.Person.objects.filter(name__endswith='飞') ret4 = models.Person.objects.filter(name__iendswith='飞') # print(ret1) # print(ret2) # print(ret3) # print(ret4) ret = models.Person.objects.filter(birth__day=1) ret = models.Person.objects.filter(birth__day=1) ret = models.Person.objects.filter(birth__contains='2018-08') print(ret)
ForeignKey操作:(一对多)
正向查找:
我们都知道,外键是建在多的对象中的,从多到一的查找是正向查询,反之就是反向查询。
#正向查询 #基于对象查询 book_obj = models.Book.objects.filter(id=5).first() # print(book_obj.title) # print(book_obj.publisher) # print(book_obj.publisher.id) # print(book_obj.publisher.name) #基于字段的查询 ret = models.Book.objects.filter(publisher__name='沙河出版社') ret = models.Book.objects.filter(publisher__id=1) # print(ret) # for i in ret: # print(i.publisher.name)
反向查找:
#反向查询 # 没有在外键中指定related_name,使用pub_obj.book_set.all() 拿所有出版社关联的书籍对象 ret = models.Publisher.objects.get(id=1) # print(ret.book_set.all()) # print(ret.book_set.first()) # print(ret.book_set.values('title')) # 在外键中指定related_name = 'bookkk',使用pub_obj.books.all() 拿所有出版社关联的书籍对象 # print(ret.bookkk.all()) #基于字段的查询 ret = models.Publisher.objects.filter(bookkk__title='西游记') # print(ret)
ManyToManyField:
author_obj = models.Author.objects.first() # print(author_obj.books.all()) author_obj.books.create(title='按时的德国',publisher_id = 1) # 1. 先创建书籍对象 # 2. 创建author_obj和新建书籍对象的对应关系 shahe = models.Publisher.objects.first() # print(shahe.book_set.all()) # print(shahe.books.all()) shahe.book_set.create(title='跟进老板学十大') author_obj.books.add(16)# 给作者添加id为16的书 author_obj.books.set([])#清空作者和所有书籍的关系 books_obj = models.Book.objects.filter(publisher_id=1) author_obj.books.add(*books_obj)#给作者添加publisher_id=1的书 author_obj.books.remove(*books_obj) #移除作者的publisher_id=1的书 # set可以添加可以删除,是更新的意思,set里放的是列表【】 #remove,add()添加或删除的都是一个一个的对象用*打散。 author_obj.books.set(books_obj) author_obj.books.clear()
注意:
对于ForeignKey对象,clear()和remove()方法仅在外键null=True时存在。
pub_obj = models.Publisher.objects.first()
pub_obj.book_set.clear()
聚合查询和分组查询:
聚合:
aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。
键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。
用到的内置函数:
from django.db.models import Avg, Sum, Max, Min, Count
示例:
ret = models.Book.objects.aggregate(Avg('price')) print(ret)
结果是:
{'price__avg': 80.42913}
如果你想要为聚合值指定一个名称,可以向聚合子句提供它。
ret = models.Book.objects.aggregate(pingjun = Avg('price')) print(ret)
结果为:
{'pingjun': 80.42913}
也可以有多个聚合值:
ret = models.Book.objects.aggregate(pingjun = Avg('price'),zonghe=Sum('price'),shuliang=Count('id')) ret = models.Book.objects.aggregate(Avg('price'),Sum('price'),Count('id')) print(ret)
分组:
#统计每一本书的作者个数 ret = models.Book.objects.annotate(Count('author')).values() # print(ret) # for i in ret: # print(i) #统计出每个出版社买的最便宜的书的价格 ret = models.Publisher.objects.annotate(Min('books__price')).values() # for i in ret: # print(i) #统计不止一个作者的图书 ret = models.Book.objects.annotate(Count('author')).values().filter(author__count__gt=1) # for i in ret: # print(i) #根据一本图书作者数量的多少对查询集 QuerySet进行排序 ret = models.Book.objects.annotate(Count('author')).values().order_by('author__count__gt') # print(ret) #查询各个作者出的书的总价格 ret = models.Author.objects.annotate(Sum('books__price')).values() print(ret)
F查询和Q查询:当两个字段进行比较的时候就会用到F查询和Q查询
F查询:
from django.db.models import F, Q #比较book中库存小于sale的书籍 # ret = models.Book.objects.filter(kucun__lt=F('sale')) # for i in ret: # print(i.title,i.kucun,i.sale) #将id为1的书名改为。 # book_obj=models.Book.objects.get(id=1) # book_obj.title='西游记啊啊啊' # book_obj.save() #另一种更改书名的方法 利用queryset # models.Book.objects.filter(id=1).update(title='西游记') #给书的kucun加上点书 加减乘除运算 # models.Book.objects.all().update(kucun=F('kucun')+100) #把所有书名后面加上(第一版),先引入 # from django.db.models.functions import Concat from django.db.models import Value models.Book.objects.all().update(title=Concat(F('title'),Value('(第一版)')))
Q查询:
#查寻id小于3大于5的书籍 | & ~ ret = models.Book.objects.filter(Q(id__lt=3)|Q(id__gt=5)).values() ret = models.Book.objects.filter(Q(id__lt=3)& Q(id__gt=5)).values() #查询id不为3且小于5的书籍 ret = models.Book.objects.filter(~Q(id=3),id__lt=5) # for i in ret: # print(i)
事务:
只要一件事不成功,整件事就失败。要成功都成功,一件事失败整件事就回滚。以转账为例,我给你打钱成功了,但是你没收到,这整件事就是不成功的。
import os if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled4.settings") import django django.setup() from app01 import models try: from django.db import transaction with transaction.atomic(): #创建山河银行, models.Publisher.objects.create(name='山和银行') #然后查询id为100的publisher models.Publisher.objects.get(id=100) #这必然是不成功的,因为publisher中不存在id为100的publisher所以,之前的创建也没有创建成功 except Exception as e: print(str(e))