Django的orm中get和filter的不同


Django的orm框架對於業務復雜度不是很高的應用來說還是不錯的,寫起來很方面,用起來也簡單。對於新手來說查詢操作中最長用的兩個方法get和filter有時候一不注意就會犯下一些小錯誤。那么今天就來小節下這兩個方法使用上的不同。

 

首先對比下兩個函數文檔上的解釋。

get

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.

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等

  • 返回值
    get 返回值是一個定義的model對象
    filter 返回值是一個新的QuerySet對象,然后可以對QuerySet在進行查詢返回新的QuerySet對象,支持鏈式操作
    QuerySet一個集合對象,可使用迭代或者遍歷,切片等,但是不等於list類型(使用一定要注意)

  • 異常
    get 只有一條記錄返回的時候才正常,也就說明get的查詢字段必須是主鍵或者唯一約束的字段。當返回多條記錄或者是沒有找到記錄的時候都會拋出異常
    filter 有沒有匹配的記錄都可以

     

    一.先說下django的get方法:

    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

    使用

    student = Student.objects.get(name='python')
    book = Book.objects.get(student)

    它也會報錯,因為book表有2條記錄和student表相匹配。

     

    二.再說下django filter:


    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 (雙下換線)進行多對多的關聯查詢(形式和一對多)


  • 免責聲明!

    本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



     
    粵ICP備18138465號   © 2018-2025 CODEPRJ.COM