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。

django LookUp的更多相关文章

  1. Django admin模块使用search时报错:django.core.exceptions.FieldError: Related Field got invalid lookup: contains

    日志如下: <class 'django.core.handlers.wsgi.WSGIRequest'> ------------registered_admins: {'spaceCl ...

  2. Django中search fields报错:related Field has invalid lookup: icontains

    models.py 文件 # coding:utf8from django.db import models class Book(models.Model):        name = model ...

  3. django fields lookup methods(lookup类型)

    __exact        精确等于 like 'aaa' __iexact    精确等于 忽略大小写 ilike 'aaa' __contains    包含 like '%aaa%' __ic ...

  4. “全能”选手—Django 1.10文档中文版Part1

    本文是博主翻译的Django1.10版本官方文档的第一部分,如时间充裕,争取一直翻译下去,经验不足,或有错漏,敬请指正. 另外对于公开文档进行翻译的版权问题不是很清楚,如有侵权请联系我! 另外,要转载 ...

  5. 【转】Django Model field reference学习总结

    Django Model field reference学习总结(一) 本文档包含所有字段选项(field options)的内部细节和Django已经提供的field types. Field 选项 ...

  6. python框架之django

    python框架之django 本节内容 web框架 mvc和mtv模式 django流程和命令 django URL django views django temple django models ...

  7. Django基础之安装配置

    安装配置 一 MVC和MTV模式 著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业务对象与数据库的 ...

  8. Django进阶(三)

    ORM 众所周知有很多不同的数据库系统,并且其中的大部分系统都包含Python接口,能够让我们更好的利用它们的功能,而这些系统唯一的缺点就是需要你了解SQL,如果你是一个更愿意操纵Python对象,而 ...

  9. 利用django创建一个投票网站(一)

    这是教程的原始链接:http://django-intro-zh.readthedocs.io/zh_CN/latest/part1/ 创建你的第一个 Django 项目, 第一部分 来跟着实际项目学 ...

随机推荐

  1. MySQL系统时间函数NOW(),CURRENT_TIMESTAMP(),SYSDATE()的区别

    CURRENT_TIMESTAMP是NOW的同义词,也就是说两者是相同的. SYSDATE函数返回的是执行到当前函数时的时间,而NOW返回的是执行SQL语句时的时间. 测试语句: SELECT NOW ...

  2. UGUI 自动布局的重叠BUG

    1,父级使用了verticalLayout(注意没有ContentSizeFilter),子级使用了ContentSizeFilter时,点击Apply常常发现,本来布局好的UI突然重叠到了一起,或位 ...

  3. Java中instanceof和isInstance的具体区别

    Java中instanceof和isInstance的具体区别 在Think in Java泛型这一章遇到这个问题,一些博客模糊提到了isInstance是instanceof的动态实现,查阅文档参考 ...

  4. RouterOS DNS劫持(转)

    什么是DNS劫持 DNS劫持就是通过技术手段,来控制用户解析域名的IP地址.举个例子,正常解析域名www.awolf.net时应该返回IP:64.64.30.60:但现在通过DNS劫持,使域名www. ...

  5. [iOS]使用autolayout的时候会有明明设置和父视图左右间距为0但却还有空隙问题

    有时候设置左右与父视图间距为0但却还有空隙,relative to margin 作怪,到关系里面,把这个取消掉.如关系里面的 firstitem 如果显示 xxView.trailling.marg ...

  6. ssh框架,工具类调用service层方法

    解决方法: @Component//声明为spring组件 public class CopyFileUtil{ @Autowired private DataFileManager dataFile ...

  7. Hibernate一对多操作

    --------------------siwuxie095 Hibernate 一对多操作 以客户和联系人为例,客户是一,联系人是多 即 一个客户里面有多个联系人,一个联系人只能属于一个客户 注意: ...

  8. svm原理及opencv

    转自http://www.cnblogs.com/justany/archive/2012/11/23/2784125.html

  9. vmware workstation 12 密钥

    VMware Workstation 12序列号:5A02H-AU243-TZJ49-GTC7K-3C61N

  10. Web测试实践--Rec 4

    累计完成任务情况: 阶段内容 参与人 整理小组工作记录,维护小组博客 小尹 分析产品并撰写文档相关板块 小靳 撰写文档中对被测系统进行功能性分析相关板块 小龙.小黄 撰写文档中用户调研相关板块 小熊 ...