zoukankan      html  css  js  c++  java
  • Django数据操作

    1.一个模型类代表数据库中的一个表,一个模型类的实例代表这个数据库表中的一条特定的记录。

    2.管理器和查询集。

    • 查询集QuerySet表示从数据库中取出来的对象的集合。它可以含有零个、一个或者多个过滤器。过滤器基于所给的参数限制查询的结果。查询集有可迭代和可切片的特点。
    • 每个模型都至少有一个管理器,它默认命名为objects管理器只可以通过模型的类访问,而不可以通过模型的实例访问,目的是为了强制区分“表级别”的操作和“记录级别”的操作。
    >>>Blog.objects
    <django.db.models.manager.Manager object at ...>
    >>> b = Blog(name='Foo', tagline='Bar')
    >>> b.objects
    Traceback:
        ...
    AttributeError: "Manager isn't accessible via Blog instances."
    

    3.创建、更改,并保存一个实例

     from blog.models import Blog
     b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
     b.save()
    b.name = 'New name'
    b.save()

      注意:在调用b.save()时,Django才正真访问数据库。

      也可以使用管理器的create方法,一步创建和保存。

    p = Person.objects.create(first_name="Bruce", last_name="Springsteen")
    
    • 更新ForeignKey 字段的方式和保存普通字段相同 —— 只要把一个正确类型的对象赋值给该字段。
    • 更新ManyToManyField 的方式有一些不同 —— 需要使用字段的add()方法来增加关联关系的一条记录。为了在一条语句中,向ManyToManyField添加多条记录,可以在调用add()方法时传入多个参数
    from blog.models import Author
    joe = Author.objects.create(name="Joe")
    entry.authors.add(joe)
    

      可以使用update() 方法为一个查询集中所有对象的某个字段都设置一个特定的值。

    # Update all the headlines with pub_date in 2007.
    Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')
    

    4.获取对象(大多数情况下,需要从数据库中查找对象时,会使用all()、 get()filter() 和exclude()。 然而,这只是冰山一角;查询集方法的完整列表,请参见查询集API 参考https://docs.djangoproject.com/en/1.10/ref/models/querysets/。

    • 获取所有对象
    all_blogs = Blog.objects.all()
    

      all()方法返回包含数据库中所有对象的一个查询集

    • 可以使用filter(**kwargs),exclude(**kwargs)设置过滤条件,返回一个新的查询子集。
    Entry.objects.filter(headline__startswith='What').exclude(pub_date__gte=datetime.date.today())
    
    • 每次筛选一个查询集,得到的都是全新的另一个查询集,它和之前的查询集之间没有任何绑定关系。每次筛选都会创建一个独立的查询集,它可以被存储及反复使用。如下:这三个查询集都是独立的。
    >>> q1 = Entry.objects.filter(headline__startswith="What")
    >>> q2 = q1.exclude(pub_date__gte=datetime.date.today())
    >>> q3 = q1.filter(pub_date__gte=datetime.date.today())
    
    • 查询集 是惰性执行的 —— 创建查询集不会带来任何数据库的访问。直到查询集需要求值时,Django 才会真正运行这个查询。
    • 可以使用字段查询,指定字段范围,形式为field__lookuptype=value(中间是两个下划线)。
    Entry.objects.filter(pub_date__lte='2006-01-01')
    Entry.objects.get(headline__exact="Man bites dog")
    Blog.objects.get(name__iexact="beatles blog")
    Entry.objects.get(headline__contains='Lennon')
    

      大约有二十多种查询的类型。查询条件中指定的字段必须是模型字段的名称。但有一个例外,对于ForeignKey你可以使用字段名加上_id 后缀。

    Entry.objects.filter(blog_id=4)
    
    • 多表关联查询:Django 提供一种强大而又直观的方式来“处理”查询中的关联关系,只需使用关联的模型字段的名称,并使用双下划线分隔。
    #from django.db import models
    
    #class Blog(models.Model):
    #    name = models.CharField(max_length=100)
    
    #class Author(models.Model):
    #    name = models.CharField(max_length=50)
       
    #class Entry(models.Model):
    #    blog = models.ForeignKey(Blog)
    #    authors = models.ManyToManyField(Author)
     
    Entry.objects.filter(blog__name='Beatles Blog')
    

     这种跨越可以是任意的深度。它还可以反向工作。若要引用一个“反向”的关系,只需要使用该模型的小写的名称。

    Blog.objects.filter(entry__headline__contains='Lennon')
    
    • 如果知道只有一个对象满足你的查询,可以使用管理器get() 方法,它直接返回该对象:
    one_blog = Blog.objects.get(pk=1)
    

      如果没有结果满足查询,get() 将引发一个DoesNotExist 异常。类似地,如果有多条记录满足get() 的查询条件,Django 也将报错。这种情况将引发MultipleObjectsReturned异常。

    • 可以使用切片和索引限制查询集。
    #切片
    Blog.objects.all()[5:10]
    Blog.objects.all()[:10:2]
    #索引
    Blog.objects.order_by('headline')[0]
    

      通常,查询集 的切片返回一个新的查询集 —— 它不会执行查询。有一个例外,是如果你使用Python 切片语法中"step"参数。

    • 其他常用的查询API包括:
      • order_by:对查询结果排序。
      • reverse:对查询结果反向排序。
      • distinct:从返回结果中剔除重复记录。
      • values:返回一个ValuesQuerySet —— QuerySet 的一个子类,迭代时返回字典而不是模型实例对象。
      • values_list:与values() 类似,只是在迭代时返回的是元组而不是字典。
      • count:返回在数据库中对应的 QuerySet.对象的个数。
      • first,last,earliest,latest:返回QuerySet.对象的第一、最后、最早、最近的一条记录。
      • exists:如果QuerySet 包含任何结果,则返回True,否则返回False
    • 聚合函数和分组函数:
      • aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。
    >>> from django.db.models import Avg, Max, Min
    >>> Book.objects.aggregate(average_price=Avg('price'), Max('price'), Min('price'))
    {'average_price': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
    
      • 逐个对象的汇总结果可以由annotate()子句生成。annotate()子句被指定之后,QuerySet中的每个对象都会被注上特定的值。与 aggregate() 不同的是, annotate() 不是一个终止子句。annotate()子句的返回结果是一个查询集 (QuerySet);这个 QuerySet可以用任何QuerySet方法进行修改,包括 filter()order_by(), 甚至是再次应用annotate()
    # Build an annotated queryset
    >>> from django.db.models import Count
    >>> q = Book.objects.annotate(num_authors=Count('authors'))
    >>> q[0].num_authors
    2
    >>> q[1].num_authors
    1
    
      • 在聚合函数中指定聚合字段时,Django 允许你使用同样的 双下划线 表示关联关系;也同样可以用关联模型的小写名称和双下划线表示"反转"关系。
    • 使用Q 对象进行复杂的查询:Q 对象可以使用& 和| 操作符组合起来,可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。

    Poll.objects.get(
        Q(question__startswith='Who'),
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
    )
    
    • 比较对象:为了比较两个模型实例,只需要使用标准的Python 比较操作符,即双等于符号:==在后台,它会比较两个模型主键的值。

     5.删除对象

      delete()方法将立即删除对象且没有返回值。 

    Entry.objects.filter(pub_date__year=2005).delete()
    

       注意,delete() 是唯一没有在管理器 上暴露出来的查询集方法。这是一个安全机制来防止你意外地请求Entry.objects.delete(),而删除所有 的条目。如果你确实想删除所有的对象,你必须明确地请求一个完全的查询集:

    Entry.objects.all().delete()
    

    6.复制对象

      最简单的方法是,只需要将pk 设置为None。 

    blog = Blog(name='My blog', tagline='Blogging is easy')
    blog.save() # blog.pk == 1
    
    blog.pk = None
    blog.save() # blog.pk == 2
    

      

     

  • 相关阅读:
    es5预览本地文件、es6练习代码演示案例
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 838 推多米诺(暴力模拟)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 837 新21点(DP)
    Java实现 LeetCode 836 矩形重叠(暴力)
    Subversion under Linux [Reprint]
    Subversion how[Reprint]
  • 原文地址:https://www.cnblogs.com/pemp/p/6066727.html
Copyright © 2011-2022 走看看