Django Queryset几个不常见的api

1、related_name
django还有一种通过对象访问相关联表数据的方法,即用_set。但是这种方法只能是相关类访问定义了关系的类(主键类访问外键类)。

class Blog(models.Model):
    pass

class Entry(models.Model):
    blog = models.ForeignKey(Blog)

如:b.entry_set.all() #b是一个blog对象

另外还有就是如果Entry中blog属性的定义如果改成这样:blog=models.ForeignKey(Blog,related_name='entries')这样的话就可以像下面这样通过blog对象得到entry对象的一个集合:


b=Blog.objects.get(id=1) b.entries.all() #==b.entry_set.all()# b.entries is a Manager that returns QuerySets. b.entries.filter(headline__contains='Lennon') b.entries.count()

2、values和values_list
返回的类似列表和字典的形式

Blog.objects.values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]

3、selected_related()
使用selected_related()的时候会自动的查询相关的外键的关系,这样可能会减少数据库查询的次数。

#查询数据库
e = Entry.objects.get(id=5)
#会再次查询数据库
b = e.blog

#查询数据库
e = Entry.objects.select_related().get(id=5)
#不会查询数据库了
b = e.blog

参考
https://docs.djangoproject.com/en/1.6/ref/models/querysets/#django.db.models.query.QuerySet.select_related

4、select_for_update
在部分大并发的时候,我们更新数据之前要先锁住记录,select_for_update就可以做到这个。

All matched entries will be locked until the end of the transaction block, meaning that other transactions will be prevented from changing or acquiring locks on them.

Usually, if another transaction has already acquired a lock on one of the selected rows, the query will block until the lock is released. If this is not the behavior you want, call select_for_update(nowait=True). This will make the call non-blocking. If a conflicting lock is already acquired by another transaction, DatabaseError will be raised when the queryset is evaluated.

Currently, the postgresql_psycopg2, oracle, and mysql database backends support select_for_update(). However, MySQL has no support for the nowait argument. Obviously, users of external third-party backends should check with their backend’s documentation for specifics in those cases.

Passing nowait=True to select_for_update() using database backends that do not support nowait, such as MySQL, will cause a DatabaseError to be raised. This is in order to prevent code unexpectedly blocking.

5、bulk_create
这个可以在一次数据库查询的时候创建多条记录

Entry.objects.bulk_create([
     Entry(headline="Django 1.0 Released"),
     Entry(headline="Django 1.1 Announced"),
     Entry(headline="Breaking: Django is awesome")
])

6、

gt
Greater than.

Example:

Entry.objects.filter(id__gt=4)
SQL equivalent:

SELECT ... WHERE id > 4;
gte
Greater than or equal to.

lt
Less than.

lte
Less than or equal to.

7、注意在使用Date查询DateTimeField的range的时候,不包括最后一天的。例如

import datetime
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))

这时候会生成这样的sql语句
SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
如果里面的start_date等是DateTimeField的时候,就会产生这样的sql语句
SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';

    原文作者:virusdefender
    原文地址: https://segmentfault.com/a/1190000000668800
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞