Django的orm中get和filter的不一样

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 有没有匹配的记录均可以

     

    一.先说下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 (双下换线)进行多对多的关联查询(形式和一对多)

  • 相关文章
    相关标签/搜索