你所需要的,不仅仅是一个好用的代理。
F() 返回的实例用作查询内部对模型字段的引用,Django支持对对象使用加法、减法、乘法、除法、取模以及幂计算等算术操作.
Entry.objects.filter(n_comments__gt=F('n_pingbacks') * 2) # n_pingbacks为一个字段
当面对多值查询的时候,需要注意使用filter,一种是同时满足条件,另一种是至少满足条件。
为了避免查询的内容不一致,可以先将查询集进行缓存;但是如果访问查询集中不存在的部分,那么后面的部分查询集将不会保存。
如果使用Q对象,那么其必须位于所有关键字参数的前面。
Poll.objects.get(
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
question__startswith='Who')
注意,delete() 是唯一没有在管理器 上暴露出来的查询集方法。这是一个安全机制来防止你意外地请求Entry.objects.delete(),而删除所有 的条目。如果你确实想删除所有的对象,你必须明确地请求一个完全的查询集:
update() 方法会立即执行并返回查询匹配的行数。如果你想保存查询集中的每个条目并确保每个实例的save() 方法都被调用,你不需要使用任何特殊的函数来处理。只需要迭代它们并调用save():
for item in my_queryset:
item.save()
常用的字段包括:
和使用 filter() 子句一样,作用于某个查询的annotate() 和 values() 子句的使用顺序是非常重要的。如果values() 子句在 annotate() 之前,就会根据 values() 子句产生的分组来计算注解。
但是,如果 annotate() 子句在 values()子句之前,就会根据整个查询集生成注解。在这种情况下,values() 子句只能限制输出的字段范围。
Author.objects.annotate(average_rating=Avg('book__rating')) # 根据作家id进行分组Author.objects.values('name').annotate(average_rating=Avg('book__rating')) # 根据作家名字进行分组
如果在 Meta 中指定了排序方式,那么在annotate的时候则会将默认的排序方式也作为一个分组项,所以要将其默认排序方式进行清空,做法如下:
Item.objects.values("data").annotate(Count("id")).order_by()
可以继承自models.Manger,从而自定义管理器。需要注意的是,如果使用自定义的管理器对象,Django会将遇到的第一位当成默认的管理器。可以在Meta中指定base_manager_name,这样就不用自己去写创建的代码。
Django如何处理:
注意在抽象模型上面定义一个自定义管理器的时候,不能调用任何使用这个抽象模型的方法,需要通过子管理器来使用。比如,这样就是错的:
AbstractBase.objects.do_something()
Django 为自定义管理器的开发者提供了一种方式:无论开发的管理器类是不是默认的管理器,它都应该可以用做自动管理器。 可以通过在管理器类中设置 use_for_related_fields属性来做到这点。
class MyManager(models.Manager):
use_for_related_fields = True # 注意是在管理器中进行定义
但是需要注意的是,不要在这种类型的管理器子类中过滤掉任何结果,一个原因是自动管理器是用来访问关联模型的对象。 在这种情况下,Django 必须要能看到相关模型的所有对象,所以才能根据关联关系得到任何数据 ;如果过滤掉了数据,那么会使得它所在的管理器不适于用做自动管理器。
有两种方式,分别是使用ORM提供的函数或者不用ORM,但要注意的是,需要防止SQL注入。
for p in Person.objects.raw('SELECT * FROM myapp_person'):
print(p)
这里的myapp_person,Django会去从指定的myapp中找到对应的模型。
也可以通过字典的方式来传递参数,使用函数的参数params可以完全防止SQL注入攻击,不要使用字符串的连接。:
name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)
当对其的结果进行数量的限制时,直接对数据库进行操作,这样可以稍微提升效率。