django LookUp
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的更多相关文章
- Django admin模块使用search时报错:django.core.exceptions.FieldError: Related Field got invalid lookup: contains
日志如下: <class 'django.core.handlers.wsgi.WSGIRequest'> ------------registered_admins: {'spaceCl ...
- Django中search fields报错:related Field has invalid lookup: icontains
models.py 文件 # coding:utf8from django.db import models class Book(models.Model): name = model ...
- django fields lookup methods(lookup类型)
__exact 精确等于 like 'aaa' __iexact 精确等于 忽略大小写 ilike 'aaa' __contains 包含 like '%aaa%' __ic ...
- “全能”选手—Django 1.10文档中文版Part1
本文是博主翻译的Django1.10版本官方文档的第一部分,如时间充裕,争取一直翻译下去,经验不足,或有错漏,敬请指正. 另外对于公开文档进行翻译的版权问题不是很清楚,如有侵权请联系我! 另外,要转载 ...
- 【转】Django Model field reference学习总结
Django Model field reference学习总结(一) 本文档包含所有字段选项(field options)的内部细节和Django已经提供的field types. Field 选项 ...
- python框架之django
python框架之django 本节内容 web框架 mvc和mtv模式 django流程和命令 django URL django views django temple django models ...
- Django基础之安装配置
安装配置 一 MVC和MTV模式 著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业务对象与数据库的 ...
- Django进阶(三)
ORM 众所周知有很多不同的数据库系统,并且其中的大部分系统都包含Python接口,能够让我们更好的利用它们的功能,而这些系统唯一的缺点就是需要你了解SQL,如果你是一个更愿意操纵Python对象,而 ...
- 利用django创建一个投票网站(一)
这是教程的原始链接:http://django-intro-zh.readthedocs.io/zh_CN/latest/part1/ 创建你的第一个 Django 项目, 第一部分 来跟着实际项目学 ...
随机推荐
- script放置最佳位置(转载)
html文件是自上而下的执行方式,但引入的css和javascript的顺序有所不同,css引入执行加载时, 程序仍然往下执行,而执行到<script>脚本是则中断线程,待该script脚 ...
- Spring IOC的配置使用
1.1.1 XML配置的结构一般配置文件结构如下: <beans> <import resource=”resource1.xml” /> <bean id=”bean1 ...
- MySQL数据库篇之多表查询
主要内容: 一.多表连接查询 二.复合条件连接查询 三.子查询 1️⃣ 多表连接查询 一.准备表 #建表 create table department( id int, name varchar( ...
- Makefile里面打印信息
Makefile的规则相对来说还是比较复杂的,上手不容易,没有系统研究过,往往搞不清楚状况.如果掌握了基本的调试手段,那对我们写出正确的Makefile会非常有帮助.而在Makefile中,最重要的调 ...
- Spark会产生shuffle的算子
去重 def distinct() def distinct(numPartitions: Int) 聚合 def reduceByKey(func: (V, V) => V, numParti ...
- 【总结整理】AI产品经理大会2017(转载)
从企业大数据到企业 AI | 易观智慧院院长 李智 1.AI 不是目的,而是要了解 AI 是什么,真正意义上的强人工智能在前沿领域尚未取得突破,暂时只能在影视文学作品中去思考人机关系.机器人三定律在未 ...
- SpringCloud04 服务配置中心、消息总线、远程配置动态刷新
1 环境说明 JDK:1.8 MAVENT:3.5 SpringBoot:2.0.5.RELEASE SpringCloud:Finchley.SR1 2 创建服务注册中心(Eureka服务端) 说明 ...
- C++ split
/*************************************************Function: splitDescription: 根据空格切分字符串Calls: // 被本函 ...
- 14-敌兵布阵(HDU1166线段树 & 树状数组)
http://acm.hdu.edu.cn/showproblem.php?pid=1166 敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory ...
- Luogu 4705 玩游戏
看见这个题依稀想起了$5$月月赛时候的事情,到现在仍然它感觉非常神仙. 游戏$k$次价值的期望答案 $$ans_k = \frac{1}{nm}\sum_{i = 1}^{n}\sum_{j = 1} ...