接上篇。直接来看django中的简单查询,

##
## SELECT `blog_author`.`id`, `blog_author`.`name`, `blog_author`.`email` FROM `blog_author` WHERE `blog_author`.`id` = 66
##
author = Author.objects.get(id=author.id)   

get只允许返回一个对象,返回多个对象可以采用filter,

authors = Author.objects.filter(name='solilo')
print connection.queries[-1] # no sql printed

仅仅使用filter并不会真的执行sql,django在这里是lazy的处理方式,在去访问filter返回的结果时才会真正连接数据库执行相应逻辑,

##
## SELECT `blog_author`.`id`, `blog_author`.`name`, `blog_author`.`email` FROM `blog_author` WHERE `blog_author`.`name` = solilo
##
authors = Author.objects.filter(name='solilo')
for author in authors:
    print author.name
print connection.queries[-1]

filter返回的是query set,query set是lazy执行这一点非常有用,这意味着可以组合创建复杂的filter来实现功能更强的查询,

## 只查询指定字段
##
## SELECT `blog_author`.`name` FROM `blog_author` WHERE `blog_author`.`name` = solilo  LIMIT 21
##
res = Author.objects.filter(name='solilo').values('name')
print res // [{'name':'solilo'}...]
print connection.queries[-1]

res = Author.objects.filter(name='solilo').values_list('name', flat=True)
print res // ['solilo'...]
print connection.queries[-1]

上面的查询都是查询单一对象,当查询对象包含外键时又会如何呢,

##
## SELECT `blog_post`.`id`, `blog_post`.`author_id`, `blog_post`.`title`, `blog_post`.`content`, `blog_post`.`timestamp`
## FROM `blog_post` WHERE `blog_post`.`title` = django notes  LIMIT 21
##
posts = Post.objects.filter(title=post.title)
for post in posts:
##
## SELECT `blog_author`.`id`, `blog_author`.`name`, `blog_author`.`email` FROM `blog_author` WHERE `blog_author`.`id` = 60
##
print post.author

可以看到首先只select了post表,后续访问post.author时候才真正去查询了author表。这也是需要小心注意的地方,这种默认处理方式的问题在于访问列表元素的外键域时可能会产生性能问题,因为这些数据不是一次被获取到的。

当然这点还是可以避免的,

##
## SELECT `blog_post`.`id`, `blog_post`.`author_id`, `blog_post`.`title`, `blog_post`.`content`, `blog_post`.`timestamp`, `blog_author`.`id`, `blog_author`.`name`, `blog_author`.`email` FROM `blog_post` INNER JOIN `blog_author` ON (`blog_post`.`author_id` = `blog_author`.`id`) WHERE `blog_post`.`title` = djaogo notes
##
posts = Post.objects.select_related().filter(title=post.title)
for post in posts:
  print post

使用select_related后相关联的字段也被一次性获取过来了,这样性能问题就得到了缓解。在实际使用时候需要根据情况来判定究竟是不是一并获取相应数据。

更多查询相关内容还是参看官方文档吧。