Django QuerySet 查询或过滤特定字段中的 "Odd" and/or "Even" 值
Django QuerySet querying or filtering "Odd" and/or "Even" value in a particular field
# Example
from django.db import models
class ParkingLot(models.Model):
lot_number = models.IntegerField()
is_reserved = models.BooleanField()
我对 Odd xor Even lot_number
很感兴趣。
在 Django 中过滤它的推荐方法是什么?
我在下面发布了一些答案。
挑战
有谁知道我们是否可以使用类似 F('lot_number') % 2 == 0
技术的直接比较?
此查询可以在 Python 级别完成。
parking_lots = list(ParkingLot.objects.all()) # Hit Database once
odd_lots = parking_lots[0::2]
even_lots = parking_lots[1::2]
这个查询可以在数据库层完成。
even_lots = ParkingLot.objects.filter(id__iregex='^\d*[02468]$') # Hit Database
odd_lots = ParkingLot.objects.filter(id__iregex='^\d*[13579]$') # Hit Database
在幕后,偶数查询集将创建以下 SQL 查询。
SELECT *
FROM parkinglot
WHERE id REGEXP '^\d*[02468]$'
前提是我们对奇数感兴趣XOR
偶数。我相信这应该是首选方法。但是,我不确定,但听说正则表达式很慢。
更新
查看@jproffitt,那应该是最好的。
在 Django >1.8 中你可以使用 F() expressions:
# ParkingLots with even numbered lot_numbers
ParkingLot.objects.annotate(odd=F('lot_number') % 2).filter(odd=False)
# ParkingLots with odd numbered lot_numbers
ParkingLot.objects.annotate(odd=F('lot_number') % 2).filter(odd=True)
虽然这在旧版本的 Django 中不起作用。
# Example
from django.db import models
class ParkingLot(models.Model):
lot_number = models.IntegerField()
is_reserved = models.BooleanField()
我对 Odd xor Even lot_number
很感兴趣。
在 Django 中过滤它的推荐方法是什么?
我在下面发布了一些答案。
挑战
有谁知道我们是否可以使用类似 F('lot_number') % 2 == 0
技术的直接比较?
此查询可以在 Python 级别完成。
parking_lots = list(ParkingLot.objects.all()) # Hit Database once
odd_lots = parking_lots[0::2]
even_lots = parking_lots[1::2]
这个查询可以在数据库层完成。
even_lots = ParkingLot.objects.filter(id__iregex='^\d*[02468]$') # Hit Database
odd_lots = ParkingLot.objects.filter(id__iregex='^\d*[13579]$') # Hit Database
在幕后,偶数查询集将创建以下 SQL 查询。
SELECT *
FROM parkinglot
WHERE id REGEXP '^\d*[02468]$'
前提是我们对奇数感兴趣XOR
偶数。我相信这应该是首选方法。但是,我不确定,但听说正则表达式很慢。
更新
查看@jproffitt,那应该是最好的。
在 Django >1.8 中你可以使用 F() expressions:
# ParkingLots with even numbered lot_numbers
ParkingLot.objects.annotate(odd=F('lot_number') % 2).filter(odd=False)
# ParkingLots with odd numbered lot_numbers
ParkingLot.objects.annotate(odd=F('lot_number') % 2).filter(odd=True)
虽然这在旧版本的 Django 中不起作用。