Django的orm框架對於業務複雜度不是很高的應用來講仍是不錯的,寫起來很方面,用起來也簡單。對於新手來講查詢操做中最長用的兩個方法get和filter有時候一不注意就會犯下一些小錯誤。那麼今天就來小節下這兩個方法使用上的不一樣。html
首先對比下兩個函數文檔上的解釋。 python
get linux
Returns the object matching the given lookup parameters, which should be in the format described in Field lookups. 數據庫
get() raises MultipleObjectsReturned if more than one object was found. The MultipleObjectsReturned exception is an attribute of the model class. django
get() raises a DoesNotExist exception if an object wasn’t found for the given parameters. This exception is also an attribute of the model class 緩存
filter 框架
Returns a new QuerySet containing objects that do not match the given lookup parameters. 運維
The lookup parameters (**kwargs) should be in the format described in Field lookups below. Multiple parameters are joined via AND in the underlying SQL statement, and the whole thing is enclosed in a NOT(). 函數
輸入參數
get 的參數只能是model中定義的那些字段,只支持嚴格匹配
filter 的參數能夠是字段,也能夠是擴展的where查詢關鍵字,如in,like等linux運維
返回值
get 返回值是一個定義的model對象
filter 返回值是一個新的QuerySet對象,而後能夠對QuerySet在進行查詢返回新的QuerySet對象,支持鏈式操做
QuerySet一個集合對象,可以使用迭代或者遍歷,切片等,可是不等於list類型(使用必定要注意)
異常
get 只有一條記錄返回的時候才正常,也就說明get的查詢字段必須是主鍵或者惟一約束的字段。當返回多條記錄或者是沒有找到記錄的時候都會拋出異常
filter 有沒有匹配的記錄均可以
1django的get方法是從數據庫的取得一個匹配的結果,返回一個對象,若是記錄不存在的話,它會報錯。
好比我數據庫裏有一條記錄,記錄的author的值是oldboy的話,我用b=Book.objects.get(author="oldboy"),
返回的是一個記錄對象,你能夠經過b . _ _ dict _ _來查看,它返回的是一個字典的形式,{’key’:valeus},key是字段的名稱,而values是值的內容。
而若是我用get方法來查詢一個數據庫裏不存在的記錄,程序會報錯。
好比:b=Book.objects.get(name='老王')
,你本身能夠運行看下。
2若是你用django的get去取得關聯表的數據的話,而關鍵表的數據若是多於2條的話也會報錯。
好比個人student表裏有一個記錄:
d name age 1 python 24 book表: id student_id 1 1 2 1 |
使用
它也會報錯,由於book表有2條記錄和student表相匹配。
1django的filter方法是從數據庫的取得匹配的結果,返回一個對象列表,若是記錄不存在的話,它會返回[]。
好比我數據庫裏有一條記錄,記錄的name的值是老王python的話,我用student = Student.objects.filter(name='老王python')
它返回的student是一個對象的列表,能夠看的出來student[0]和上面的get方式返回的student的結果是同樣的。
2若是你用django的get去取得關聯表的數據的話,不管關聯表有多少記錄的都不會報錯。
django 除了model比較強大的話,表單和模板也很強大.
另外我從別的資料裏看到filter好像有緩存數據的功能,第一次查詢數據庫並生成緩存,下次再調用filter方法的話,直接取得緩存的數據,會get方法每次執行都是直接查詢數據庫的,不知道這個是否是正確。
表記錄的增
models.Publisher.objects.create(name="沙河出版社")
表記錄的改
方式一:
b=Book.objects.get(author="oldboy") b.price=120 b.save() 方式二:#update是QuerySet Book.objects.filter(author="yuan").update(price=999)
表記錄的刪book_list = Book.objects.filter(id=2) book_list=Book.objects.exclude(author="yuan").values("name","price") book_list=Book.objects.all() book_list = Book.objects.all()[::2] book_list = Book.objects.all()[::-1] #first,last,get取到的是一個實例對象,並不是一個QuerySet的集合對象 book_list = Book.objects.first() book_list = Book.objects.last() book_list = Book.objects.get(id=2)#只能取出一條記錄時纔不報錯 ret1=Book.objects.filter(author="oldboy").values("name") ret2=Book.objects.filter(author="yuan").values_list("name","price") book_list= Book.objects.all().values("name").distinct() book_count= Book.objects.all().values("name").distinct().count()
models.Publisher.object.get(id=1).delete()
Book.objects.filter(author="oldboy").delete()
模糊查詢 雙下劃線__
book_list=Book.objects.filter(name__icontains="P").values_list("name","price")book_list=Book.objects.filter(id__gt=5).values_list("name","price")
外鍵的增刪改查
增刪查同上
book_obj = models.Publisher.object.filter(id=1)
book_obj.publisher是什麼?
和我這本書關聯的出版社對象
book_obj.publisher.id 是和我這本書關聯的出版社id值
book_obj.publisher.name 是和我這本書關聯的出版社名稱
多表操做(一對多):
#添加記錄
#publish_id=2
Book.objects.create(name="linux運維",price=77,pub_date="2017-12-12",publish_id=2)
#publish=object
Book.objects.create(name="GO",price=23,pub_date="2017-05-12",publish=publish_obj)
#查詢記錄(經過對象)
正向查詢:
book_obj=Book.objects.get(name="python")
pub_obj=book_obj.publish----》書籍對象對應的出版社對象
pub_obj.name
反向查詢:
pub_obj = Publish.objects.filter(name="人民出版社")[0]
pub_obj.book_set.all().values("name","price")
#查詢記錄(filter values 雙下劃線__)
#人民出版社出版過的書籍與價格
ret=Book.objects.filter(publish__name="人民出版社").values("name","price")
#python這本書出版社的名字
ret2=Publish.objects.filter(book__name="python").values("name")
#python這本書出版社的名字
ret3=Book.objects.filter(name="python").values("publish__name")
#北京的出版社出版書的名字
ret4=Book.objects.filter(publish__city="北京").values("name")
#2017年上半年出版過書的出版社的名字
ret5=Book.objects.filter(pub_date__lt="2017-07-01",pub_date__gt="2017-01-01").values("publish__name")
多表操做(多對多):1.查id爲1的做者寫過的書?
author_obj=models.Author.objects.get(id=1)
author_obj.books.all()
2.想給做者綁定多本書?
author_obj=models.Author.objects.get(id=1)
author_obj.books.set([1,2,3]) --->把id是1,2,3的書和我這個做者關聯
建立多對多的關係 author= models.ManyToManyField("Author")(推薦)
書籍對象它的全部關聯做者 obj=book_obj.authors.all()
綁定多對多的關係 obj.add(*QuerySet)
obj.remove(author_obj)
若是想向第三張表插入值的方式綁定關係: 手動建立第三張表# class Book_Author(models.Model): # book=models.ForeignKey("Book") # author=models.ForeignKey("Author") Book_Author.objects.create(book_id=2,author_id=3) 掌握:經過 filter values (雙下換線)進行多對多的關聯查詢(形式和一對多)