Custom Lookups

一个简单LookUp例子

Author.objects.filter(name__ne='Jack')
# Translate SQL
"author"."name" <> 'Jack'

自定义

from django.db.models import Lookup
from django.db.models.fields import Field @Field.register_lookup
class NotEqual(Lookup):
lookup_name = "ne" def as_sql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return '%s <> %s' % (lhs, rhs), params Field.register_lookup(NotEqual) # 注册 或者使用 @Field.register_lookup装饰器

一个简单的Transform例子

from django.db.models import Transform

class AbsoluteValue(Transform):
lookup_name = 'abs'
function = 'ABS' from django.db.models import IntegerField # 只应用在数字字段
IntegerField.register_lookup(AbsoluteValue)
Experiment.objects.filter(change__abs=27)
# generate SQL
SELECT ... WHERE ABS("experiments"."change") = 27 Experiment.objects.filter(change__abs__lt=27)
# generate SQL
SELECT ... WHERE ABS("experiments"."change") < 27 Experiment.objects.order_by('change__abs')
# generate SQL
SELECT ... ORDER BY ABS("experiments"."change") ASC

output_filed

rom django.db.models import FloatField, Transform

class AbsoluteValue(Transform):
lookup_name = 'abs'
function = 'ABS' @property
def output_field(self):
return FloatField()

Writing an efficient abs_lt lookup

在使用上述编写的abs查找时,在某些情况下生成的SQL不会有效地使用索引。特别是,当我们使用change__abs__lt=27时,这就相当于change__gt=-27和change__lt=27。(对于lte,我们可以使用SQL BETWEEN)。

因此,我们想要用experimental .objects.filter(change__abs__lt=27)来生成以下SQL:

SELECT .. WHERE "experiments"."change" < 27 AND "experiments"."change" > -27
The implementation is:

from django.db.models import Lookup

class AbsoluteValueLessThan(Lookup):
lookup_name = 'lt' def as_sql(self, compiler, connection):
lhs, lhs_params = compiler.compile(self.lhs.lhs)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params + lhs_params + rhs_params
return '%s < %s AND %s > -%s' % (lhs, rhs, lhs, rhs), params AbsoluteValue.register_lookup(AbsoluteValueLessThan)

A bilateral transformer example

我们前面讨论的AbsoluteValue示例是一个应用于查找左边的转换。在某些情况下,你可能想把变换应用到左边和右边。例如,如果您想根据左边和右边的等式对某个SQL函数不敏感地过滤一个queryset。

from django.db.models import Transform

class UpperCase(Transform):
lookup_name = 'upper'
function = 'UPPER'
bilateral = True
from django.db.models import CharField, TextField
CharField.register_lookup(UpperCase)
TextField.register_lookup(UpperCase)
Author.objects.filter(name__upper="doe")
# generate SQL
SELECT ... WHERE UPPER("author"."name") = UPPER('doe')

Writing alternative implementations for existing lookups

有时,不同的数据库供应商对相同的操作需要不同的SQL。对于本例,我们将为NotEqual操作符重写MySQL的自定义实现。我们将使用!=操作符,而不是<>。(请注意,实际上几乎所有数据库都支持这两种方法,包括Django支持的所有官方数据库)。

我们可以通过使用as_mysql方法创建NotEqual的子类来更改特定后端上的行为

class MySQLNotEqual(NotEqual):
def as_mysql(self, compiler, connection):
lhs, lhs_params = self.process_lhs(compiler, connection)
rhs, rhs_params = self.process_rhs(compiler, connection)
params = lhs_params + rhs_params
return '%s != %s' % (lhs, rhs), params Field.register_lookup(MySQLNotEqual)

然后我们可以将它注册到Field。它取代了原来的NotEqual类,因为它具有相同的lookup_name。

在编译查询时,Django首先查找as_%s %连接。然后返回到as_sql。内置后端的厂商名称是sqlite、postgresql、oracle和mysql。

How Django determines the lookups and transforms which are used

在某些情况下,您可能希望根据传入的名称动态更改返回的转换或查找,而不是修复它。例如,您可以有一个存储坐标或任意维度的字段,并希望允许像.filter(coords__x7=4)这样的语法返回第7个坐标值为4的对象。为了做到这一点,您可以使用类似的方法重写get_lookup

class CoordinatesField(Field):
def get_lookup(self, lookup_name):
if lookup_name.startswith('x'):
try:
dimension = int(lookup_name[1:])
except ValueError:
pass
else:
return get_coordinate_lookup(dimension)
return super().get_lookup(lookup_name)

查找顺序:

如果匹配上Lookup,查找Lookup,如果没匹配上,查找Transform,在从Truansform查找LookUp。

最新文章

  1. 吐槽贴:百度地图 api 封装 的实用功能 [源码下载]
  2. Spring JDBC
  3. Java 基础知识 练习
  4. python--ulipad控制台中文输出乱码
  5. APP弱网测试
  6. 浅谈php对api开发的作用
  7. iis8 默认不支持svc解决方法
  8. 用MyGeneration模板生成NHibernate映射文件和关系
  9. CentOS-Desktop版service network restart报错
  10. Leetcode: Find Permutation(Unsolve lock problem)
  11. Linux下安装、启动、停止mongodb
  12. uva 674 Coin Change 换钱币【完全背包】
  13. 逆袭之旅DAY24.XIA.二重进阶、双色球
  14. element 表格元素 超链接
  15. (1.2)mysql 索引概念
  16. php中的释放语句unset和释放函数mysql_free_result()
  17. Flash(as3) 调整显示对象颜色
  18. maven -- 问题解决(一)解决eclipse中maven项目配置过程和maven install时出现的问题
  19. Egret引擎开发基础(一)
  20. linux shell执行原理

热门文章

  1. Bower 使用
  2. 10+ 最佳的 Node.js 教程和实例
  3. 使用Windows绘图合成多张图
  4. 高性能Web服务器Nginx的配置与部署研究(3)Nginx请求处理机制
  5. Android 重写EditText回车事件
  6. 525. Contiguous Array两位求和为1的对数
  7. CentOS 6.4一键自动化安装ISO镜像光盘
  8. 利用django中间件CsrfViewMiddleware防止csrf攻击
  9. cacti-不出图形,cacti.log中出“ERROR: SQL Assoc Failed!
  10. Springboot-读取核心配置文件及自定义配置文件