單表查詢
queryset對象就可以無限制的點queryset方法
新增數據
基於Queryset
models.對應表的類名.objects.create(字段名 = 值,……)
基於對象
object = models.對應表的類名(字段名 = 值,……)
object.save()
修改數據
基於Queryset
models.對應表的類名.objects.filter(字段名 = 值[查找條件]).update(字段名=值[更改後的數據])
基於對象
object = models.對應表的類名.objects.filter(字段名 = 值[查找條件]).first()
object.字段名 = 值
object.save()
刪除數據
基於Queryset
models.對應表的類名.objects.filter(字段名 = 值[查找條件]).delete()
基於對象
object = models.對應表的類名.objects.filter(字段名 = 值[查找條件]).first()
object.delete()
查詢數據
1.all()
: 查詢所有結果
2.filter(**kwargs)
: 它包含了與所給篩選條件相匹配的對象,filter內可以放多個限制條件,多個條件之間是and關係
3.get(**kwargs)
: 返回與所給篩選條件相匹配的對象,返回結果有且只有一個,如果符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
4.exclude(**kwargs)
: 它包含了與所給篩選條件不匹配的對象
5.order_by(*field)
: 對查詢結果排序,默認是以括號裏的值升序排列,在值前面加上負號-就是降序排列
6.reverse()
: 對查詢結果反向排序,前面要先有排序才能反向
7.count()
: 返回數據庫中匹配查詢(QuerySet) 的對象數量
8.first()
: 返回第一條記錄
9.last()
: 返回最後一條記錄
10.exists()
: 如果QuerySet包含數據,就返回True,否則返回False
11.values(*field)
: 返回一個ValueQuerySet——一個特殊的QuerySet,運行後得到的並不是一系列model的實例化對象,而是一個可迭代的字典序列
12.values_list(*field)
: 它與values()非常相似,它返回的是一個元組序列(列表套元祖),values返回的是一個字典序列
13.distinct()
: 從返回結果中剔除重複紀錄 去重的對象必須是完全相同的數據才能去重(例如若id不同但其他所有都相同的記錄不會被刪除,但我們先指定相同的字段,再針對此刪除相同的數據)
雙劃線查詢
語法:字段名__查詢條件=值
1.__gt=值 :大於……的
2.__gte=值 :大於等於……的
3.__lt=值 :小於……的
4.__lte=值 :小於等於……的
5.__in=[值1,值2,……]:在列表的值中的
6.__range=[x,y] :在x和y範圍內的
7.__year=值 :年份
8.__contains=值:包含……的(大小寫敏感)
9.__icontains=值:包含……的(大小寫不敏感)
10.__startswith=值:以……開頭的
11.__endswith=值:以……開頭的
多表查詢
栗子:
數據庫設計
圖書表book:id,title,price,publish_date
作者表author:id,name,age
出版社表publish:id,name,addr,email
作者詳情表:id,phone,addr
表之間的關係
圖書表和作者表是多對多關係
圖書表和出版社表是多對一關係
作者表和作者詳情表是一對一關係
模型表
class Book(models.Model):
# 主鍵不指定默認創建id字段爲主鍵
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish_date = models.DateField(auto_now_add=True) # auto_now:每次操作改數據都會自動更新時間,auto_now_add:新增數據的時候會將當前時間自動添加,後續的修改該字段不會自動更新
# 外鍵關係
publish = models.ForeignKey(to='Publish')
authors = models.ManyToManyField(to='Author') # 虛擬字段, 信號字段
def __str__(self):
return '書籍對象的名字:%s'%self.title
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
email = models.EmailField() # 對應就是varchar類型
def __str__(self):
return '出版社對象的名字:%s'%self.name
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
authordetail = models.OneToOneField(to='AuthorDetail')
def __str__(self):
return '作者對象的名字:%s'%self.name
class AuthorDetail(models.Model):
phone = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
爲外鍵關係字段賦值
1.直接寫數據:publish_id=1
models.Book.objects.create(title='紅樓夢',price=66.66,publish_id=1)
2.傳數據對象:publish=publish_obj
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='三國演義',price=199.99,publish=publish_obj)
表與表之間添加關係
add:支持傳數字或對象,並且都可以傳多個
表1_object = models.對應表1的類名.objects.filter(字段名 = 值[查找條件]).first()
表1_object.與表2的關聯字段.add(數字或表2對象)
表與表之間修改關係
set:傳的必須是可迭代對象(用元祖形式)
表1_object = models.對應表1的類名.objects.filter(字段名 = 值[查找條件]).first()
表1_object.與表2的關聯字段.set((數字,)或表2對象)
表與表之間刪除關係
remove:需要將queryset打散,*<queryset>
表1_object = models.對應表1的類名.objects.filter(字段名 = 值[查找條件]).first()
表1_object.與表2的關聯字段.remove((數字,)或打散的表2對象)
清空表與表之間的關係
clear():清空的是你當前這個表記錄對應的綁定關係
表1_object = models.對應表1的類名.objects.filter(字段名 = 值[查找條件]).first()
表1_object.與表2的關聯字段.clear()
基於對象的表查詢
正向查詢與反向查詢:正向查詢按字段,反向查詢按表名小寫
判斷正向查詢與反向查詢的依據是關聯字段是否在表內
正向
表1_object = models.對應表1的類名.objects.filter(字段名 = 值[查找條件]).first()
表1_object.與表2的關聯字段[.all()].表2字段
反向
表2_object = models.對應表2的類名.objects.filter(字段名 = 值[查找條件]).first()
表2_object.與表1名小寫_set[.all()].表1字段
多對一關係和多對多關係如果不加.all()
會顯示項目名.對應表的類名.None
,因爲對應關係查出來的結果會多於一個,而一對一關係則不需要加。
基於雙下滑線的查詢
正向
models.對應表1的類名.objects.filter(字段名 = 值[查找條件]).value(與表2關係字段__查詢的字段名)
反向
models.對應表2的類名.objects.filter(字段名 = 值[查找條件]).value(對應表1的類名小寫__查詢的字段名)
聚合查詢aggregate
導入聚合函數from django.db.models import Max,Min,Count,Sum,Avg
models.對應表的類名.objects.filter(字段名 = 值[查找條件]).aggregate(別名=聚合函數(字段名[雙下劃線查詢適用]))
分組查詢annotate
models.對應表的類名.objects.annotate(別名=聚合函數(字段名[雙下劃線查詢適用])).values(分組字段,別名)