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. iOS学习之第二个View使用UITabBarViewController

    前面有一篇博文iOS学习之Tab Bar的使用和视图切换 这是在AppDelegate里使用Tabbar,这样的程序打开就是TabbarView了,有时候我们需要给程序做一些帮助页面,或者登录页面,之 ...

  2. 两个不同vim之间复制内容

    常规想法是打开两个vim,然后进行yy和p操作,但是实践证明根本是不行的.此时,我们需要分割窗口,然后就可以复制粘贴了.步骤如下: 假设我要把srv.c文件的readline函数整体复制到cli.c文 ...

  3. HttpClient由Client客户端上传File文件流至Server服务端

    客户端方法 public static void main(String[] args) { File file=new File("E:\\lucene\\rev\\全年平台受理量.doc ...

  4. fsync性能问题

    最近在测试种发现程序里调用fsync刷文件到磁盘时,开销只有几百微秒,于是对fsync相关机制进行了一番调查. 磁盘(或RAID卡)自身通常会有硬件缓存机制,对于写操作,有write back和wri ...

  5. 【HDU - 5442】Favorite Donut 【最大表示法+KMP/后缀数组】

    题意 给出一个长度为n的环状由小写字母组成的序列,请找出从何处断开,顺时针还是逆时针,使得字典序最大.如果两个字符串的字典序一样大,那么它会选择下下标最小的那个.如果某个点顺时针逆时针产生的字典序大小 ...

  6. 【UVA11212 算法竞赛入门经典】 Editing a Book 【IDA*】

    题意 你有一篇由n(2<=n<=9)个自然段组成的文章,希望将它们排列成1,2,···,n.可以用剪切和粘贴来完成任务.每次可以剪切一段连续的自然段,粘贴时按照顺序粘贴.注意剪贴板只有一个 ...

  7. Mask_rcnn openpose realsense

    cd /home/luo/Desktop/MyFile/Mask_RCNN_Openpose_Realsense python realsense_mask_openpose_2019032601.p ...

  8. 303. Range Sum Query 范围求和系列

    Immutable [抄题]: Given an integer array nums, find the sum of the elements between indices i and j (i ...

  9. SQLSERVER Tempdb的作用及优化

    tempdb 系统数据库是可供连接到 SQL Server 实例的所有用户使用的全局资源.tempdb 数据库用于存储下列对象:用户对象.内部对象和版本存储区. 用户对象 用户对象由用户显式创建.这些 ...

  10. 美化input type=range标签滑动样式(带渐变效果)

    input原来的样式就不在此赘述了: 下面看一下实际项目中用到的input输入框,同步绑定输入数据,实现输入框双向绑定(实际项目中使用的是vue框架): html部分: <div class=& ...