哨兵

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  1. model对应数据库表,model的实例则对应表中的一条记录.
    from blog.models import Blog
    b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
    #调用save后才会在表中生成记录,b.id才会有值,因为id是数据库生成的
    #此处save相当于调用了insert语句
    b.save()
    b.name="Tom"
    #此处save相当于调用update语句
    b.save()

    #create方法包含创建对象并save到数据库
    Blog.objects.create(name='news Blog', tagline='All news.')
    添加ForeignKey和ManyToManyField的field值
    from blog.models import Entry
    entry = Entry.objects.get(pk=1)
    cheese_blog = Blog.objects.get(name="Cheddar Talk")
    #ForeighnKey成员,直接赋值
    entry.blog = cheese_blog
    entry.save()
    
    #ManyToManyField成员需要调用add方法
    joe = Author.objects.create(name="Joe")
    entry.authors.add(joe)
    
    #添加多个成员时
    paul = Author.objects.create(name="Paul")
    george = Author.objects.create(name="George")
    ringo = Author.objects.create(name="Ringo")
    entry.authors.add(paul,george,ringo)
  2. 每个model class都有一个Manager成员,默认名字为objects,注意是model class而不是model instance,Model.objects.all()返回所有QuerySet包含所有表中的对象.注意QuerySet是lazy的,创建时候并不会执行实际操作,只有evaluated时才真正执行操作。可以通过下面两个函数返回满足一定条件的QuerySet:
    • filter(**kwargs):满足指定查询条件的QuerySet
    • exclude(**kwargs):不满足查询条件的QuerySet
  3. 每个QuerySet都包含一个cache,以减少对数据库的访问,刚定义queryset时cache为空,evluated后cache就有值了,之后访问queryset都是访问cache中的值
    #执行两次数据库查询
    print([e.headline for e in Entry.objects.all()])
    print([e.pub_date for e in Entry.objects.all()])
    
    queryset = Entry.objects.all()
    print([p.headline for p in queryset]) # Evaluate the query set.
    print([p.pub_date for p in queryset]) # Re-use the cache from the evaluation.
    
    queryset = Entry.objects.all()
    #只返回queryset中的一部分
    print queryset[5] # Queries the database
    print queryset[5] # Queries the database again
    
    queryset = Entry.objects.all()
    [entry for entry in queryset] # Queries the database
    print queryset[5] # Uses cache
    print queryset[5] # Uses cache
    
    #如下操作都会导致queryset evaluated,填充cache
    [entry for entry in queryset]
    bool(queryset)
    entry in queryset
    list(queryset)
  4. 可以返回QuerySet中的子集,相当于sql语句中的limit和offset
    Entry.objects.all()[:5]
    Entry.objects.all()[5:10]
    Entry.objects.order_by('headline')[0]
  5. 返回单个对象使用get方法,如果对象不存在会抛出Model.DoesNotExist异常,如果有多个满足条件的对象则抛出Model.MultipleObjectsReturned异常。注意此处与QuerySet object[0]的区别,如果没有获取满足条件的QuerySet,用下标取对象会抛出IndexError的异常
  6. field查询:filter,get等函数都使用field进行查询,如果field不存在则会抛TypeError异常。例外的是以ForeignKey类型的field作查询参数时,可以在该field后面加”_id”,
    #查找外键blog id=4的所有Entry
    Entry.objects.filter(blog_id=4)
    一些比较常用的查询关键字:
    • exact:精确匹配,默认使用
      #效果相同
      Blog.objects.get(id__exact=14) 
      Blog.objects.get(id=14)
    • iexact:匹配时忽略大小写
    • contains:包含查询,大小写敏感
      #相当于SELECT ... WHERE headline LIKE '%Lennon%';
      Entry.objects.get(headline__contains='Lennon')
    • icontains:包含查询,大小写不敏感
    • startswith,endswith:匹配开头或结尾,大小写敏感
    • istartswith,iendswith:匹配开头或结尾,大小写不敏感
    • in:是否在某个list中
    • gt,lt,gte,lte等比较操作
    • year,month,day,week_day,hour,minute,seconde等时间操作
    • isnull:是否为空
  7. 跨relationship的field查询,
    #entry与blog是多对一的关系
    Entry.objects.filter(blog__name='Beatles Blog')
    Blog.objects.filter(entry__headline__contains='Lennon')
    #entry与authors是多对多关系
    Blog.objects.filter(entry__authors__name='Lennon')
    Blog.objects.filter(entry__authors__name__isnull=True)
    Blog.objects.filter(entry__authors__isnull=False,
       entry__authors__name__isnull=True)
    注意下面代码的区别
    #返回的blog 同时满足参数中的两个条件
    Blog.objects.filter(entry__headline__contains='Lennon',
            entry__pub_date__year=2008)
    #blog包含多个entry,只要其中有两个分别满足下面两个条件,就返回blog
    Blog.objects.filter(entry__headline__contains='Lennon').filter(
            entry__pub_date__year=2008)
  8. F class:用于获取model field的值
    Q class:用于定义重用查询条件,Q objects可以使用&和|进行组合,这样会生成新的Q object,field的查询关键字都可以在Q object的参数中使用
    Q(question__startswith='Who') | ~Q(pub_date__year=2005)
    Poll.objects.get(
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
        question__startswith='Who')

    reporter = Reporters.objects.get(name='Tintin')
    reporter.stories_filed += 1
    reporter.save()
    #与上面代码效果相同
    reporter = Reporters.objects.filter(name='Tintin')
    reporter.update(stories_filed=F('stories_filed') + 1)
    
    #更新所有stories_field
    Reporter.objects.all().update(stories_filed=F('stories_filed') + 1)

    Entry.objects.filter(authors__name=F('blog__name'))
  9. 删除对象使用delete()方法,model和queryset都包含此方法用于删除单个或者多个对象。对于外键对象,如果定义时设置了on_delete参数为true,那么删除外键对象时会把指向该外键对象的对象也删除
    e.delete()
    Entry.objects.filter(pub_date__year=2005).delete()
    Entry.objects.all().delete()
    
    b = Blog.objects.get(pk=1)
    # This will delete the Blog and all of its Entry objects.
    b.delete()
  10. 复制对象:
    • 简单情况
      blog = Blog(name='My blog', tagline='Blogging is easy')
      blog.save() # blog.pk == 1
      # 设置pk为None
      blog.pk = None
      blog.save() # blog.pk == 2
    • 继承类
      class ThemeBlog(Blog):
          theme = models.CharField(max_length=200)
      
      django_blog = ThemeBlog(name='Django', tagline='Django is easy', theme='python')
      django_blog.save() # django_blog.pk == 3
      #需要设置id和pk为None
      django_blog.pk = None
      django_blog.id = None
      django_blog.save() # django_blog.pk == 4
    • 上面两种方式都不给related object赋值,赋值related object的代码如下:
      entry = Entry.objects.all()[0] # some previous entry
      old_authors = entry.authors.all()
      entry.pk = None
      entry.save()
      entry.authors = old_authors # saves new many2many relations
posted on 2014-09-30 12:33  哨兵  阅读(931)  评论(0编辑  收藏  举报