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_paramsreturn '%s <> %s' % (lhs, rhs), paramsField.register_lookup(NotEqual)  # 注册 或者使用 @Field.register_lookup装饰器

一个简单的Transform例子

from django.db.models import Transformclass 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") = 27Experiment.objects.filter(change__abs__lt=27)
# generate SQL
SELECT ... WHERE ABS("experiments"."change") < 27Experiment.objects.order_by('change__abs')
# generate SQL
SELECT ... ORDER BY ABS("experiments"."change") ASC

output_filed

rom django.db.models import FloatField, Transformclass AbsoluteValue(Transform):lookup_name = 'abs'function = 'ABS'@propertydef 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 Lookupclass 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_paramsreturn '%s < %s AND %s > -%s' % (lhs, rhs, lhs, rhs), paramsAbsoluteValue.register_lookup(AbsoluteValueLessThan)

A bilateral transformer example

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

from django.db.models import Transformclass 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_paramsreturn '%s != %s' % (lhs, rhs), paramsField.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:passelse:return get_coordinate_lookup(dimension)return super().get_lookup(lookup_name)

查找顺序:

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

转载于:https://www.cnblogs.com/LTEF/p/9736806.html

django LookUp相关推荐

  1. django后台搜索显示Related Field got invalid lookup: icontains

    项目场景: django后台搜索 问题描述 输入搜索后显示字段错误类型并报Related Field got invalid lookup: icontains的错误 原因分析: 根据百度查找原因是查 ...

  2. Django进阶-auth集成认证模块

    auth认证模块是Django内置集成的一个用户认证模块. auth认证模块方法 方法 释义 auth.authenticate() 认证校验 auth.login(request,user) 封装认 ...

  3. Django REST framework API 指南(12):验证器

    官方原文链接 本系列文章 github 地址 转载请注明出处 验证器 大多数情况下,您在 REST framework 中处理验证时,只需依赖默认的字段验证,或者在序列化类或字段类上编写明确的验证方法 ...

  4. django官方文档1.11编翻:1-1-1概述

    django概述 因为django是在快节奏的编辑环境下开发的,它旨在使常见的Web开发任务变得快速而简单. 这是一个关于如何用django编写数据库驱动的Web应用程序的非正式概述. 本文档的目的是 ...

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

    欢迎大家访问我的个人网站<刘江的博客和教程>:www.liujiangblog.com ### 主要分享Python 及Django教程以及相关的博客 本文是博主翻译的Django1.10 ...

  6. Django入门教程(二)

    建议直接阅读末尾!!! Writing your first Django app, part 2 本节将设置数据库,创建您的第一个模型(model),并简单介绍Django自动生成的管理页面. 数据 ...

  7. django学习之Model(四)MakingQuery

    上一篇写到MakingQuey中的filter,本篇接着来. 10)-扩展多值的关系 如果对一个ManyToManyField或ForeignKey的表进行filter过滤查询的话,有2中方法可以用. ...

  8. Django REST framework+Vue 打造生鲜超市(五)

    六.商品类别数据展示 6.1. 商品类别数据接口 (1)商品分类有两个接口: 一种是全部分类:一级二级三级 一种是某一类的分类以及商品详细信息: 开始写商品分类的接口 (2)序列化 给分类添加三级分类 ...

  9. xadmin oracle 查询,Django admin 实现search_fields精确查询实例

    我就废话不多说了,还是直接看代码吧! search_fields = (u'gift_rule_id',u'user_id', u'activity_id',) //默认的查询集合 def get_q ...

  10. Writing your first Django app--Django 第一步

    主页链接:https://docs.djangoproject.com/en/1.6/intro/tutorial01/ Let's learn by example.使用例子进行学习. Throug ...

最新文章

  1. 某大厂程序员哀叹:千万不要从大厂往小厂跳,后悔死了!小厂只会逼迫压榨,刚来就一个劲要产出!...
  2. 魔改ResNet反超Transformer再掀架构之争!作者说“没一处是创新”,这些优化trick值得学...
  3. 如何更好的与人沟通?[图]
  4. 不吹不黑,赞一下应用运维管理的cassacdra
  5. tensorflow 标准数据读取 tfrecords
  6. Spring Data Solr教程:排序
  7. 企业如何对付DDoS***
  8. 聚类分析-K均值matlab(一)
  9. Markdown公式编辑总结
  10. 通过百度BAE搭建微信二次开发的服务(2)
  11. 火线 零线 中线 地线
  12. awk 中使用 OFS.
  13. 程序员如何阅读英文资料
  14. 专项审计有哪些?专项审计报告包含哪些内容?
  15. 怎么更换当前电脑的ip(ip被网站封了无法访问怎么办)
  16. w ndows无法连接到System,Windows无法连接到System Event Notification Service服务解决方法...
  17. 关于华为实习的一两点感触
  18. OGNL中#、%和$的用法
  19. 精品网站社区地址集合
  20. JNI 之Java和c/c++交互,提升Java变成效率

热门文章

  1. web学习(3)--别踩白块儿(HTML版)(web入门)
  2. 《我们在时光的列车上,没有终点》
  3. 制作一个简单HTML旅游网站(HTML+CSS+JS)无锡旅游网页设计与实现8个页面
  4. 计算机cpu一直超频,电脑卡顿怎么办,CPU超频让老电脑起死回生,大神带你玩转CPU!...
  5. win10通过ping命令来检测网速
  6. 通过HOST VIP连接Oracle数据库
  7. mysql relay_log删除_mysql 删除 relay log 方法
  8. JAVA POI Excel导出,数据源可以是ListMap或者ListModel类型
  9. 解决IOS微信SDK初始化失败
  10. PE系统纯净(可以识别nvme固态)