zoukankan      html  css  js  c++  java
  • django 表操作

    添加表纪录

    # Create your models here.
    class Book(models.Model):
        id = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)
        state = models.BooleanField()
        pub_date = models.DateField()
        price = models.DecimalField(max_digits=8, decimal_places=2)
        publish = models.CharField(max_length=32)

    方式1

        book_obj = models.Book(title='python web',price=29, publish='北京出版社',pub_date="2012-12-12")
        book_obj.save()

    方式2

      book_obj = models.Book.objects.create(title="java红宝书", state=True, price=100, publish="苹果出版社", pub_date="2012-12-12")

    删除表纪录

    删除方法就是 delete()。它运行时立即删除对象而不返回任何值。例如:

    model_obj.delete()
    

     按条件删除

     ret = models.Book.objects.all().filter(price__in=[100, 88]).delete()
    

     级联删除

    在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。例如:

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()
    
        def __str__(self):              # __unicode__ on Python 2
            return self.name
    
    class Author(models.Model):
        name = models.CharField(max_length=200)
        email = models.EmailField()
    
        def __str__(self):              # __unicode__ on Python 2
            return self.name
    
    class Entry(models.Model):
        blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
        headline = models.CharField(max_length=255)
        body_text = models.TextField()
        pub_date = models.DateField()
        mod_date = models.DateField()
        authors = models.ManyToManyField(Author)
        n_comments = models.IntegerField()
        n_pingbacks = models.IntegerField()
        rating = models.IntegerField()
    
        def __str__(self):              # __unicode__ on Python 2
            return self.headline

    delete

    b = Blog.objects.get(pk=1)
    # This will delete the Blog and all of its Entry objects.
    b.delete()

    要注意的是: delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用:

    Entry.objects.all().delete()  
    

    如果不想级联删除,可以设置为:

    blog = models.ForeignKey(Blog, on_delete=models.SET_NULL, blank=True, null=True)

    删除语句

    Blog.objects.all().filter(name='python_qq').delete()

    修改表纪录

    Book.objects.filter(title__startswith="py").update(price=120)
    

     update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录update()方法会返回一个整型数值,表示受影响的记录条数。

    查询表记录

    查询API

    1> all():                  查询所有结果
      
    <2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
      
    <3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
                                如果符合筛选条件的对象超过一个或者没有都会抛出错误。
      
    <4> exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象
     
    <5> order_by(*field):       对查询结果排序
      
    <6> reverse():              对查询结果反向排序
      
    <8> count():                返回数据库中匹配查询(QuerySet)的对象数量。
      
    <9> first():                返回第一条记录
      
    <10> last():                返回最后一条记录
      
    <11> exists():              如果QuerySet包含数据,就返回True,否则返回False
     
    <12> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
                                model的实例化对象,而是一个可迭代的字典序列
    <13> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
     
    <14> distinct():            从返回结果中剔除重复纪录

    基于双下划线的模糊查询  

    Book.objects.filter(price__in=[100,200,300])
    Book.objects.filter(price__gt=100)
    Book.objects.filter(price__lt=100)
    Book.objects.filter(price__range=[100,200])
    Book.objects.filter(title__contains="python")
    Book.objects.filter(title__icontains="python")
    Book.objects.filter(title__startswith="py")
    Book.objects.filter(pub_date__year=2012)
    Entry.objects.get(headline__contains='Lennon')

    contains:

    表示包含的意思!大小写敏感!

    icontains:

    contains的大小写不敏感模式。

    startswith和endswith

    以什么开头和以什么结尾。大小写敏感!

    istartswith和iendswith

    是不区分大小写的模式。

    查询操作练习

        # 1
        # 查询老男孩出版社出版过的价格大于200的书籍
    
        book_list = models.Book.objects.filter(price__gt=200, publish='老男孩出版社')
        print(book_list)
        # 2
        # 查询2017年8月出版的所有以py开头的书籍名称
        book_list = models.Book.objects.filter(title__startswith='py', pub_date__year=2017,pub_date__month=8)
        print(book_list)
        # 3
        # 查询价格为50, 100
        # 或者150的所有书籍名称及其出版社名称
        book_list = models.Book.objects.filter(price__in=[50, 100,150]).values_list('publish','title')
        print(book_list)
        # 4
        # 查询价格在100到200之间的所有书籍名称及其价格
        book_list = models.Book.objects.filter(price__range=[100,200]).values_list('title','price')
        print(book_list)
        # 5
        # 查询所有人民出版社出版的书籍的价格(从高到低排序,去重)
        book_list = models.Book.objects.filter(publish='人民出版社').values_list('price').distinct().order_by('-price')
        print(book_list)
    

      

    多表操作

    class Author(models.Model):
        nid = models.AutoField(primary_key=True)
        name=models.CharField( max_length=32)
        age=models.IntegerField()
    
        # 与AuthorDetail建立一对一的关系
        authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)
    
    
    class AuthorDetail(models.Model):
    
        nid = models.AutoField(primary_key=True)
        birthday=models.DateField()
        telephone=models.BigIntegerField()
        addr=models.CharField( max_length=64)
    
    class Publish(models.Model):
        nid = models.AutoField(primary_key=True)
        name=models.CharField( max_length=32)
        city=models.CharField( max_length=32)
        email=models.EmailField()
    
    
    class Book(models.Model):
    
        nid = models.AutoField(primary_key=True)
        title = models.CharField( max_length=32)
        publishDate=models.DateField()
        price=models.DecimalField(max_digits=5,decimal_places=2)
    
        # 与Publish建立一对多的关系,外键字段建立在多的一方
        publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
        # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
        authors=models.ManyToManyField(to='Author',)

    多对多添加方式

        book_obj = Book.objects.filter(nid=1).first()
        alex = Author.objects.create(name='alex', age='20', authorDetail_id=1)
        egon = Author.objects.create(name='egon', age='18', authorDetail_id=2)
        #
        # # 多对多添加方式
        book_obj.authors.add(alex, egon)

    跨表查询

     # 1.基于对象的查询(子查询)
        """
        A-B
        关联属性在A表
    
        正向查询 A---------B
        反向查询 B---------A
        """
        """
        一对多
        """
    
        # 正向查询查字段
        # 查询书名为红楼梦的出版社名字
        book_obj = Book.objects.filter(title='红楼梦').first()
        print(book_obj.publish.name)  # 查询关联的出版社对象
    
        # 反向查询查表名_set.all
        # 查询书名为人民出版社的书名
        publish_obj = Publish.objects.filter(name='人民出版社').first()
        print(publish_obj.book_set.all())
    
        """
        多对多
    
        """
        # 正向查询查字段
        # 查询书名为红楼梦的作者名字
        book_obj = Book.objects.filter(title='红楼梦').first()
        print(book_obj.authors.all())  # 查询关联的作者对象
    
        # 反向查询查表名_set.all
        # 查询alex写的书名
        author_obj = Author.objects.filter(name='alex').first()
        print(author_obj.book_set.all())
    
        """
        一对一查询
        """
        """
        A - B
        关联属性在A表
    
        正向查询
        A - --------B
        反向查询
        B - --------A
    
         """
    
        # 正向查询查字段
        # 查询alex作者电话
        author_obj = Author.objects.filter(name='alex').first()
        print(author_obj.authorDetail.telephone)  # 查询关联的作者细节对象
    
        # 反向查询查表名
        # 查询电话111的作者
        authorDetail_obj = AuthorDetail.objects.filter(telephone='111').first()
        print(authorDetail_obj.author.name, authorDetail_obj.author.age)
     # 2.基于双下划线的查询(join)
        # 正向查询查字段,反向查询查表名告诉orm join
    
        # 查询书名为红楼梦的出版社名字(一对多)
        """
        sql:
        select app3_publish.name from app3_book inner join app3_publish
        on app3_book.publish_id = app3_publish.nid where app3_book.title='红楼梦'
    
        """
        # 方式一
        # <QuerySet [{'publish__name': '人民出版社'}]>
        print(Book.objects.filter(title='红楼梦').values("publish__name"))
    
        # 方式二
        print(Publish.objects.filter(book__title='红楼梦').values(
            "name"))  # <QuerySet [{'publish__name': '人民出版社'}]>
    
        # 查询书名为红楼梦的作者名字(多对多)
        """
        sql:
        select name from app3_author inner join app3_book_authors on app3_author.nid = app3_book_authors.author_id
        inner join app3_book on app3_book.nid = app3_book_authors.book_id
        """
        # 方式一
        # <QuerySet [{'authors__name': 'alex,egon'}]>
        print(Book.objects.filter(title='红楼梦').values("authors__name"))
    
        # 方式二
        print(Author.objects.filter(book__title='红楼梦').values("name"))
    
        # 查询alex作者电话
        print(Author.objects.filter(name='alex').values("authorDetail__telephone"))
    
        print(AuthorDetail.objects.filter(author__name='alex').values("telephone"))
    
        # 进阶练习
        # 查询电话111作者出版过所有书籍及书籍出版社的名称
    
        # 方式1
        print(
            Book.objects.filter(
                authors__authorDetail__telephone__startswith='11').values(
                "title",
                "publish__name"))
    
        # 方式2
        print(
            Author.objects.filter(
                authorDetail__telephone__startswith='11').values(
                "book__title",
                "book__publish__name"))
    

      

    聚合查询

    from django.db.models import Count, Max, Min, Avg
    
        print(
            Book.objects.all().aggregate(
                avg_price=Avg("price"),
                max_price=Max('price'),
                min_price=Min('price')))  # 返回字典
    
        # 单表分组查询
        # 查询每一个省以及对应的员工数
    
        # emp:
        print(Emp.objects.values("province").annotate(cnt=Count("id")))
    
        # 多表分组查询
        # 查询出版社的名称及出版书籍的个数
        ret = Publish.objects.values("nid").annotate(cnt=Count("book__title"))
        print(ret)
    
        ret = Publish.objects.values("name").annotate(cnt=Count("book__title"))
        print(ret)
    
        ret = Publish.objects.values("name").annotate(
            cnt=Count("book__title")).values(
            "name", "cnt")
        print(ret)
    
        # 查询每一个作者的名字以及出版书籍的最高价格
        ret = Author.objects.values("pk").annotate(
            max_price=Max("book__price")).values(
            "name", "max_price")
        print(ret)
    
        # 查询每一个书籍的名称及对应的作者个数
        ret = Book.objects.values("pk").annotate(
            cnt=Count("authors__nid")).values(
            "title", "cnt")
        print(ret)
    
        # 统计每一本以py开头的书籍的作者个数:
        ret = Book.objects.filter(
            title__startswith="py").values("pk").annotate(
            cnt=Count("authors__nid")).values(
                "title",
            "cnt")
        print(ret)
    
        # (4)统计不止一个作者的图书
        ret = Book.objects.values("pk").annotate(
            cnt=Count("authors__nid")).filter(
            cnt__gt=1).values(
                "title",
            "cnt")
        print(ret)
    
        # F查询Q查询
        from django.db.models import F, Q
        # 统计书的评论数大于读过数
        ret = Book.objects.filter(comment_num__lt=F("read_num"))
        print(ret)
    
        Book.objects.all().update(price=F("price") + 10)
    
        ret = Book.objects.filter(Q(title='红楼梦') | Q(price__gt=100))
        print(ret)
    
        ret = Book.objects.filter(~Q(title='红楼梦') | Q(price__gt=100))
        print(ret)

    操作API

    get() 获取单个对象
    create() 创建对象,无需save()
    get_or_create() 查询对象,如果没有找到就新建对象
    update_or_create() 更新对象,如果没有找到就创建对象
    bulk_create() 批量创建对象
    count() 统计对象的个数
    in_bulk() 根据主键值的列表,批量返回对象
    iterator() 获取包含对象的迭代器
    latest() 获取最近的对象
    earliest() 获取最早的对象
    first() 获取第一个对象
    last() 获取最后一个对象
    aggregate() 聚合操作
    exists() 判断queryset中是否有对象
    update() 批量更新对象
    delete() 批量删除对象

     get()

    get(**kwargs)

    返回按照查询参数匹配到的单个对象,参数的格式应该符合Field lookups的要求。

    如果匹配到的对象个数不只一个的话,触发MultipleObjectsReturned异常

    如果根据给出的参数匹配不到对象的话,触发DoesNotExist异常。例如:

    bulk_create()

    bulk_create(objs, batch_size=None)

    以高效的方式(通常只有1个查询,无论有多少对象)将提供的对象列表插入到数据库中:

    Entry.objects.bulk_create([
    ...     Entry(headline='This is a test'),
    ...     Entry(headline='This is only a test'),
    ... ])

    注意事项:

    • 不会调用模型的save()方法,并且不会发送pre_savepost_save信号。
    • 不适用于多表继承场景中的子模型。
    • 如果模型的主键是AutoField,则不会像save()那样检索并设置主键属性,除非数据库后端支持。
    • 不适用于多对多关系。

    batch_size参数控制在单个查询中创建的对象数。

    count()

    返回在数据库中对应的QuerySet对象的个数。count()永远不会引发异常。

    latest(field_name=None)

    使用日期字段field_name,按日期返回最新对象。

    下例根据Entry的'pub_date'字段返回最新发布的entry:

    Entry.objects.latest('pub_date')

    exists()

    如果QuerySet包含任何结果,则返回True,否则返回False。

    查找具有唯一性字段(例如primary_key)的模型是否在一个QuerySet中的最高效的方法是:

    entry = Entry.objects.get(pk=123)
    if some_queryset.filter(pk=entry.pk).exists():
        print("Entry contained in queryset")
    

    它将比下面的方法快很多,这个方法要求对QuerySet求值并迭代整个QuerySet:

    if entry in some_queryset:
       print("Entry contained in QuerySet")
    

    若要查找一个QuerySet是否包含任何元素:

    if some_queryset.exists():
        print("There is at least one object in some_queryset")
    

    将快于:

    if some_queryset:
        print("There is at least one object in some_queryset")

    查询参数及聚合函数

    http://www.liujiangblog.com/course/django/132

  • 相关阅读:
    用c#小程序理解线程
    我对线程入门理解
    网站发布后IIS故障解决办法
    ASP .NET XML 文件
    SortedList 对象兼有 ArrayList 和 Hashtable 对象的特性。
    (笔记)索引器
    HOW TO:使用 Visual C# .NET 在 ASP.NET 中创建自定义错误报告
    读取EXCEL的数据到datagridview
    一个超级简单的文件流操作WINDOW应用程序
    Gridview事件
  • 原文地址:https://www.cnblogs.com/xiao-apple36/p/11523323.html
Copyright © 2011-2022 走看看