• Django的models操作


     

    一、先看单表操作

    方式1:

        models.book.objects.create(
            Book_name = "aaa",
            Book_info = "bbb",
            Book_price = "ccc",
            Book_num = "ddd"
        )
    

     

    方式2:用2个*号传递一个字典进去 

        book_info = {
            "Book_name":"aaa",
            "Book_info":"bbb",
            "Book_price":"ccc",
            "Book_num":"ddd"
        }
    
        models.book.objects.create(**book_info)
    

      

    删,通过delete方法

    可以通过表中的每个字段进行删除

    models.book.objects.filter(id=1).delete()
    
    models.book.objects.filter(Book_name="book1").delete()
    

      

    改,通过update方法,要 调用update方法,必须要querySet对象才可以,比如filter和all方法返回的是一个对象集合,通过get方法返回的单个对象是不能调用update方法的

        models.book.objects.filter(id=1).update(
            Book_name = "aaa",
            Book_info = "bbb",
            Book_price = "ccc",
            Book_num = "dd"
        )
    

      

    models.book.objects.filter(Book_name="book6").update(Book_name="aaaaaaaaaaaaaaaa")
    

      

    get方法:返回单个对象

    models.book.objects.all().get(id=2)
    

      

    filter方法:返回一个对象集合

    models.book.objects.filter(id=1)
    

      

    values方法:返回一个对象集合的字典形式,也可以只返回指定的字段

     models.book.objects.filter(id=1).values("Book_name","Book_info")
    

      

    print(models.book.objects.all().values())
    

      

    values_list方法:返回一个对象集合的列表的形式

    print(models.book.objects.all().values_list())
    

      

    count方法:统计数据的个数

    print(models.book.objects.filter(Book_name="book3").count())
    

      

    exists方法:统计对象集合中是否有数据,有则为ture,无则为false

    print(models.book.objects.filter(Book_name="book3").count())
    

     

    exclude:返回不符合某个条件的对象集合

    models.book.objects.exclude(id=2)
    

      

    order_by:按照指定的字段从小到大排列

    models.book.objects.order_by("Book_price")
    

      

    order_by:按照指定的字段从大到小排列

    models.book.objects.order_by("-Book_price")
    

      

    reverse:和orader_by加一个符号的效果一样,逆序排列

    models.book.objects.reverse("id")
    

      

    distanct:对结果去重,这里不能对单个字段去重,只能对所有的字段去重

    models.book.objects.all().distinct()
    

      

    二、在看一对多操作

    一对多和一对一基本上一样,只有插入数据这里有点不一样

        # 先看一对多
        # 我们先看下ForeignKey这个字段的值该如何插入
        # 虽然我们写的的Book_pub,但是实际上在数据库中存储的字段是Book_pub_id,所以这里有两种方式来搞
    
    
        # 如果我们知道书对应的出版社的id,则可以直接用Book_pub_id赋值这个数字就可以了
        # Book_pub_id = 4
        #
    
        # 我们还可以直接从数据库取出出版社的对象,然后Book_pub赋值给一个出版社的对象就可以了
        # Book_pub = Publish的对象
    

      

    另外一点不一样的就是,如果在一所对应的表中删除数据,那么会同步删除多表中的包含该一的字段

    比如书1的出版社是出版社1,书2的出版社是出版社1,那么如果我们在出版社表中删除出版社1,那么不仅仅出版社表中的出版社1的数据会被删除,书表中的书1和书2都会被同步删除

    我们看下一对多如何增加数据

     因为书和出版社是一对多的关系,我们先获取一个出版社对象

        publish_obj = models.Publish.objects.filter(id=5)[0]
    
        models.book.objects.create(
            Book_name = "django",
            Book_info = "这是一本写django的书",
            Book_price = 100,
            Book_num = 20000,
            Book_pub = publish_obj
            )
    

      

    或者直接赋值id

        models.book.objects.create(
            Book_name = "Flask",
            Book_info = "这是一本写Flask的书",
            Book_price = 100,
            Book_num = 20000,
            Book_pub_id = 5
            )
    

      

    我们查看数据库,已经创建了2条数据

     下面我们看下一对多的删除

    我们先删除出版社id为5的数据,看下有什么效果

    models.Publish.objects.filter(id=5).delete()
    

      

    我们发现Publish中id为5的数据已经被删除

    同样在book表中,关联publish表中id为5的数据也被删除

    我们在看下删除book表中的数据

    models.book.objects.filter(id=8).delete()
    

      

    我们看到数据库中已经删除这条数据

    我们在看改

    我们在创建两条数据

     先把book表中的数据更新

    models.book.objects.filter(id=14).update(Book_name="python教程")
    

      

    我们查看数据库发现名称已经更改

    我们在来尝试下修改publish_id

     models.book.objects.filter(id=14).update(Book_pub_id=1)
    

      

    我们在来看数据库

     发现已经更改

    我们最后来看下查

    首先我们看正向查询,正向查询的意思就在有外键的表查询

    通过all方法查看

        obj = models.book.objects.all()
        print(obj)
    

      

    结果如下

    查看某条数据的信息

        obj = models.book.objects.filter(id=13)[0]
        print(obj.Book_Auther)
        print(obj.Book_pub)
        print(obj.Book_pub_id)
    

      

    结果如下

     我们还可以通过两个下划线做跨表查询

        obj = models.book.objects.all().values("Book_name","id","Book_pub__id","Book_pub__Pub_name")
        print(obj)
    
        obj = models.book.objects.all().values_list("Book_name","id","Book_pub__id","Book_pub__Pub_name")
        print(obj)
    

      

    结果如下

    我们在来看逆向查询,通过没有外键的表查询

    1、先拿到一个对象,记住,这里不能使用对象集合,下面的例子,第一个obj是一个错误的示范

        obj = models.Auther.objects.filter(id=1)
        obj = models.Auther.objects.get(id=1)
    

      

    2、通过set方法查询,记住values里面的字段和正向查询是一样的

        obj = models.Auther.objects.get(id=1)
        #
        #
        print(obj.book_set.values("Book_name","Book_pub__Pub_name"))
    

      

    我们看结果

     我们可以查询某个出版社出版了几本书

        obj = models.Publish.objects.filter(id=1)[0]
    
        print(obj.book_set.all().count())
    

      

    我们可以查看某个出版社出版的书的名称

        obj = models.Publish.objects.filter(id=1)[0]
    
        print(obj.book_set.all().count())
    
        print(obj.book_set.all().values("Book_name"))
    

      

    三、再看多对多操作

     先看怎么创建多对多的关系

    方式1,由django为我们创建第三张表

    Book_Auther = models.ManyToManyField("Auther")
    

      

    add方法

        book = models.book.objects.filter(id=1)[0]
    
        auther1 = models.Auther.objects.filter(id=1)[0]
        auther2 = models.Auther.objects.get(id=2)
    
        book.Book_Auther.add(auther1,auther2)
    

     

    结果 

    remove方法

        book = models.book.objects.filter(id=1)[0]
    
        auther1 = models.Auther.objects.filter(id=1)[0]
        auther2 = models.Auther.objects.get(id=2)
    
        # book.Book_Auther.add(auther1,auther2)
    
        book.Book_Auther.remove(auther1)
    

      

    结果

    我们在看反向添加,在没有manytomanyfiled的表出发去执行命令,需要一个_set方法

        book1 = models.book.objects.filter(id=1)[0]
        book2 = models.book.objects.get(id=2)
    
        auther2 = models.Auther.objects.get(id=2)
    
        auther2.book_set.add(book1,book2)
    

      

    结果

    在看反向移除,也要用到_set方法

        book1 = models.book.objects.filter(id=1)[0]
        book2 = models.book.objects.get(id=2)
    
        auther2 = models.Auther.objects.get(id=2)
    
        # auther2.book_set.add(book1,book2)
        auther2.book_set.remove(book1)
    

      

    结果如下

     

    方式2、我们自己创建第三张表

    class BookToAuther(models.Model):
        book = models.ForeignKey("book")
        auther = models.ForeignKey("Auther")
    

      

    在看如何为多对多表中插入数据,我们先看下第三张表由django为我们创建的表的情况

    为一个书添加多个作者

        # 获取一个书的对象
        book_obj = models.book.objects.filter(id=1)[0]
    
        # 获取2个作者的对象
        auther1 = models.Auther.objects.filter(id=1)[0]
        auther2 = models.Auther.objects.all().get(id=2)
    
        # 为这个书添加2个作者对象
        book_obj.Book_Auther.add(auther1,auther2)
    
        # 为这个书添加2个对象的另外一种方式
        book_obj.Book_Auther.add(*[auther1,auther2
    

      

     把add换成remove就是解除绑定

    反向查询这里,book是小写的,就算你的book表是大写的,这里也要变为小写

     

    多对多,如果我们自己创建第三张表,那么就在第三表中对book和auther都写上外键,就相当于一个多对多,那么我们操作第三张表和一对多是一样的

    # 第二种方式创建多对多的第三张表class BookToAuther(models.Model):
    class BookToAuther(models.Model):
        book = models.ForeignKey("book")
        auther = models.ForeignKey("Auther")
    

      

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    我们在来看下查询的其他方法

    1、切片操作

        obj = models.book.objects.all()[0:1]
        print(obj)
    
        obj = models.book.objects.all()[0:10:2]
        print(obj)
    

      

    结果如下

    2、拿到指定书名对应的出版社的名称

        # 先拿到书的对象,然后根据外键就获取一表中的对象,然后根据这个对象就可以获取另外一张表的的字段的信息
        obj = models.book.objects.filter(Book_name="shu2")[0].Book_pub.Pub_name
        print(obj)

    结果

     

    3、拿到某个出版社出版的所有书的名称,book_set返回的是一个query_set对象

        # 先拿到出版社的对象,然后通过book_set方法拿到书这个表的内容,然后通过values方法去获取指定的字段
        obj = models.Publish.objects.filter(Pub_name="chubanshe4")[0].book_set.all().values("Book_name")
        print(obj)
    
        obj = models.Publish.objects.filter(Pub_name="chubanshe4")[0].book_set.all().values_list("Book_name")
        print(obj)
    

     结果 

     

    4、拿到id大于2的书的名称和id

        # 查询id大于2的书的名称
        obj = models.book.objects.filter(id__gt=2)
        print(obj.values("id","Book_name"))
    

      

    结果如下

    5、其他一些双下划线的单表查询的方法

     # 小于
        obj = models.book.objects.filter(id__lt=2)
    
        # 大于等于
        obj = models.book.objects.filter(id__gte=2)
    
        # 小于等于
        obj = models.book.objects.filter(id__lte=2)
    
    
        obj = models.book.objects.filter(id__in=[1,2,4,6])
    
        # 包含,区分大小写
        obj = models.book.objects.filter(Book_name__contains="chuban")
    
        # 包含,不区分大小写
        obj = models.book.objects.filter(Book_name__icontains="chuban")
    
        # 以什么开头,区分大小写
        obj = models.book.objects.filter(Book_name__startwith="chuban")
    
        # 以什么开头,不区分大小写
        obj = models.book.objects.filter(Book_name__istartwith="chuban")
        
        # 以什么结尾,区分大小写
        obj = models.book.objects.filter(Book_name__endwith="chuban")
    
        # 以什么结尾,不区分大小写
        obj = models.book.objects.filter(Book_name__iendwith="chuban")
    

      

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    关联查询

    1、查询书的名称是shu0的出版社的信息,要求是通过出版社这张表去查,这个意思book表中的 book_name字段,因为出版社中没有外键,则只能通过表名去做跨表查询

        obj = models.Publish.objects.filter(book__Book_name="shu0")
        print(obj.all())
    

      

    fiilter中可以有多个过滤的字段,这些过滤的字段通过逗号隔开,这几个字段是取交集的

    2、我们还可以通过书的表去查询出版社的信息,那么这里就不能用表明,而是用在书中的外键的字段,因为书的表中有外键,所有要用外键的字段去做跨表查询

        obj = models.book.objects.filter(Book_pub__Pub_name="chubanshe1")
        print(obj.all())
    

      

    补充一个小点,model的form验证

    我们在models中创建表,可以选择CharField,也可以选择EmailField,但是如果我们选择了EmailField,就算我们输入的不是邮箱格式,我们也可以正常插入数据,那么是不是这个字段没有作用呢?

    我们先看下例子吧

    1、在model创建表

    class test(models.Model):
        u = models.CharField(max_length=64,null=True)
        e = models.EmailField(max_length=12,null=True)
    

      

    2、然后我们插入数据

    2_1、create方法插入数据

    models.test.objects.create(u="aaaa",e="111111")
    

      

    可以插入成功

    2_2、save方法插入数据

        obj = models.test()
        obj.u = "2222"
        obj.e = "22222"
        obj.save()
    

      

    可以插入成功

    看起来这个EmailField确实没有什么作用,其实不然,如果我们这样搞的话,他就会校验数据的合法性,使用clear_fields方法,就可以校验合法性

        obj = models.test()
        obj.u = "3333"
        obj.e = "3333"
        res = obj.clean_fields()
        print(res)
        obj.save()
    

      

     我们看到后台报错了

     数据库中也没有插入数据

    如果我们输入正确的邮箱格式,则可以添加成功

        obj = models.test(u="33333",e="33333@qq.com")
        res = obj.clean_fields()
        print(res)
        obj.save()
    

     

    数据库也插入数据成功

     

    先简单的介绍下model的forms,就到此为止吧

  • 相关阅读:
    面试题八 二进制中 1 的个数
    面试题七 斐波那契数列
    面试题六 用两个栈实现队列
    第 3 章 第 2 题 求级数问题 递归法实现
    第 3 章 第 1 题 精简冗余 if 语句问题 使用数组实现
    第 2 章 第 10 题 测量电灯泡体积问题
    第 2 章 第 9 题 顺序 & 二分搜索效率分析问题
    带缓冲的IO( 标准IO库 )
    Linux 中权限控制实例
    Linux 中权限的再讨论( 下 )
  • 原文地址:https://www.cnblogs.com/bainianminguo/p/9069876.html
Copyright © 2020-2023  润新知