Conditional Expressions
Conditional Expressions建立一些逻辑关系
The conditional expression classes
from django.db import models
class Client(models.Model):
REGULAR = 'R'
GOLD = 'G'
PLATINUM = 'P'
ACCOUNT_TYPE_CHOICES = (
(REGULAR, 'Regular'),
(GOLD, 'Gold'),
(PLATINUM, 'Platinum'),
)
name = models.CharField(max_length=50)
registered_on = models.DateField()
account_type = models.CharField(
max_length=1,
choices=ACCOUNT_TYPE_CHOICES,
default=REGULAR,
)
When
对象用于封装条件及其结果,以便在条件表达式中使用。使用When()对象与使用filter()方法类似。可以使用字段查找或Q对象指定条件。使用then关键字提供结果。
>>> from django.db.models import F, Q, When
>>> # String arguments refer to fields; the following two examples are equivalent:
>>> When(account_type=Client.GOLD, then='name')
>>> When(account_type=Client.GOLD, then=F('name'))
>>> # You can use field lookups in the condition
>>> from datetime import date
>>> When(registered_on__gt=date(2014, 1, 1),
... registered_on__lt=date(2015, 1, 1),
... then='account_type')
>>> # Complex conditions can be created using Q objects
>>> When(Q(name__startswith="John") | Q(name__startswith="Paul"),
... then='name')
因为then关键字参数是为When()的结果保留的,所以如果模型有一个名为then的字段,就会有潜在的冲突。这可以通过两种方式解决:
>>> When(then__exact=0, then=1)
>>> When(Q(then=0), then=1)
Case
Case函数类似于python中的if elif else...,按照指定的When()对象的顺序求值,直到求出一个真值为止。返回匹配上的When()的对象。
>>> from datetime import date, timedelta
>>> from django.db.models import Case, CharField, Value, When
>>> Client.objects.create(
... name='Jane Doe',
... account_type=Client.REGULAR,
... registered_on=date.today() - timedelta(days=36))
>>> Client.objects.create(
... name='James Smith',
... account_type=Client.GOLD,
... registered_on=date.today() - timedelta(days=5))
>>> Client.objects.create(
... name='Jack Black',
... account_type=Client.PLATINUM,
... registered_on=date.today() - timedelta(days=10 * 365))
>>> # Get the discount for each Client based on the account type
>>> Client.objects.annotate(
... discount=Case(
... When(account_type=Client.GOLD, then=Value('5%')),
... When(account_type=Client.PLATINUM, then=Value('10%')),
... default=Value('0%'),
... output_field=CharField(),
... ),
... ).values_list('name', 'discount')
<QuerySet [('Jane Doe', '0%'), ('James Smith', '5%'), ('Jack Black', '10%')]>
Case()接受任意数量的When()对象作为单独的参数。其他选项使用关键字参数提供。如果没有条件求值为TRUE,则返回带有默认关键字参数的表达式。如果没有提供默认参数,则不使用任何参数。
如果我们想改变我们之前的查询,以获得折扣的基础上多久的客户一直与我们,我们可以这样做,使用查找:
>>> a_month_ago = date.today() - timedelta(days=30)
>>> a_year_ago = date.today() - timedelta(days=365)
>>> # Get the discount for each Client based on the registration date
>>> Client.objects.annotate(
... discount=Case(
... When(registered_on__lte=a_year_ago, then=Value('10%')),
... When(registered_on__lte=a_month_ago, then=Value('5%')),
... default=Value('0%'),
... output_field=CharField(),
... )
... ).values_list('name', 'discount')
<QuerySet [('Jane Doe', '5%'), ('James Smith', '0%'), ('Jack Black', '10%')]>
Case()也适用于filter()子句。例如,找到一个多月前注册的黄金客户和一年多前注册的白金客户:
>>> a_month_ago = date.today() - timedelta(days=30)
>>> a_year_ago = date.today() - timedelta(days=365)
>>> Client.objects.filter(
... registered_on__lte=Case(
... When(account_type=Client.GOLD, then=a_month_ago),
... When(account_type=Client.PLATINUM, then=a_year_ago),
... ),
... ).values_list('name', 'account_type')
<QuerySet [('Jack Black', 'P')]>
条件表达式可以用于annotations、aggregations、lookups和updates。它们还可以与其他表达式组合和嵌套。这允许您进行强大的条件查询。
Conditional update
>>> a_month_ago = date.today() - timedelta(days=30)
>>> a_year_ago = date.today() - timedelta(days=365)
>>> # Update the account_type for each Client from the registration date
>>> Client.objects.update(
... account_type=Case(
... When(registered_on__lte=a_year_ago,
... then=Value(Client.PLATINUM)),
... When(registered_on__lte=a_month_ago,
... then=Value(Client.GOLD)),
... default=Value(Client.REGULAR)
... ),
... )
>>> Client.objects.values_list('name', 'account_type')
<QuerySet [('Jane Doe', 'G'), ('James Smith', 'R'), ('Jack Black', 'P')]>
Conditional aggregation
>>> # Create some more Clients first so we can have something to count
>>> Client.objects.create(
... name='Jean Grey',
... account_type=Client.REGULAR,
... registered_on=date.today())
>>> Client.objects.create(
... name='James Bond',
... account_type=Client.PLATINUM,
... registered_on=date.today())
>>> Client.objects.create(
... name='Jane Porter',
... account_type=Client.PLATINUM,
... registered_on=date.today())
>>> # Get counts for each value of account_type
>>> from django.db.models import Count
>>> Client.objects.aggregate(
... regular=Count('pk', filter=Q(account_type=Client.REGULAR)),
... gold=Count('pk', filter=Q(account_type=Client.GOLD)),
... platinum=Count('pk', filter=Q(account_type=Client.PLATINUM)),
... )
{'regular': 2, 'gold': 1, 'platinum': 3}
Transform SQL
>>> # Create some more Clients first so we can have something to count
>>> Client.objects.create(
... name='Jean Grey',
... account_type=Client.REGULAR,
... registered_on=date.today())
>>> Client.objects.create(
... name='James Bond',
... account_type=Client.PLATINUM,
... registered_on=date.today())
>>> Client.objects.create(
... name='Jane Porter',
... account_type=Client.PLATINUM,
... registered_on=date.today())
>>> # Get counts for each value of account_type
>>> from django.db.models import Count
>>> Client.objects.aggregate(
... regular=Count('pk', filter=Q(account_type=Client.REGULAR)),
... gold=Count('pk', filter=Q(account_type=Client.GOLD)),
... platinum=Count('pk', filter=Q(account_type=Client.PLATINUM)),
... )
{'regular': 2, 'gold': 1, 'platinum': 3}
Conditional Expressions的更多相关文章
- Simplifying Conditional Expressions(简化条件表达式)
1.Decompose Conditional(分解条件表达式) 2.Consolidate Conditional Expressions(合并条件表达式) 3.Consolidate Duplic ...
- Replace Nested Conditional with Guard Clauses(用卫语句代替嵌套循环)
函数中的条件逻辑,使人难以看清正常的执行路径. 使用卫语句表现所有特殊情况. double getPayAmount() {double result;if (_isDead) result = de ...
- 「操作系统」: Conditional Move Instructions(trap)
Not all conditional expressions can be compiled using conditional moves. Most significantly, the abs ...
- java语言中的匿名类与lambda表达式介绍与总结 (Anonymous Classes and Lambda Expressions)
2017/6/30 转载写明出处:http://www.cnblogs.com/daren-lin/p/anonymous-classes-and-lambda-expressions-in-java ...
- Delphi CompilerVersion Constant / Compiler Conditional Defines
http://delphi.wikia.com/wiki/CompilerVersion_Constant The CompilerVersion constant identifies the in ...
- [LeetCode] Ternary Expression Parser 三元表达式解析器
Given a string representing arbitrarily nested ternary expressions, calculate the result of the expr ...
- Ternary Expression Parser
Given a string representing arbitrarily nested ternary expressions, calculate the result of the expr ...
- SH Script Grammar
http://linux.about.com/library/cmd/blcmdl1_sh.htm http://pubs.opengroup.org/onlinepubs/9699919799/ut ...
- Effective Python2 读书笔记2
Item 14: Prefer Exceptions to Returning None Functions that returns None to indicate special meaning ...
随机推荐
- Synchronized块同步变量的误区
我们可以通过synchronized块来同步特定的静态或非静态方法.要想实现这种需求必须为这些特性的方法定义一个类变量,然后将这些方法的代码用synchronized块括起来,并将这个类变量作为参数传 ...
- quartz简介
- 让你的网站用上https
一般申请了SSL证书,会有安装教程教你一步步配置.这里照搬官方教程. 下载得到的 www.domain.com.zip 文件,解压获得3个文件夹,分别是Apache.IIS.Nginx 服务器的证书文 ...
- Opencv 计算图片旋转角度
vector<vector<Point>> vec_point;vector<Vec4i> hireachy;findContours(img_canny1, ve ...
- 16-多线程爬取糗事百科(python+Tread)
https://www.cnblogs.com/alamZ/p/7414020.html 课件内容 #_*_ coding: utf-8 _*_ ''' Created on 2018年7月17日 ...
- [c++] polymorphism without virtual function
polymorphism without virtual function
- python链接
http://www.crifan.com/files/doc/docbook/python_beginner_tutorial/release/html/python_beginner_tutori ...
- vnpy自动化交易
c++ python 写的自动化交易平台 期货ctp
- java免费空间!最简单的openshift免费空间上传代码教程!和FTP一样简单!
史上最简单的openshift免费空间上传代码教程!没有之一! 最近因为想弄一个免费的空间,而且最好是Java的空间,找了一大片,jsp的空间少不说,免费的更是寥寥无几. 找了一大推垃圾空间,终于让我 ...
- 一个java多线程面试题
线程a 打印 数字 0--12: 线程b 打印 字母 a--z; 打印结果:0ab1cd2ef3gh4ij5kl6mn7op8qr9st10uv11wx12yz 要求用到 线程间传值: 分析:线程a打 ...