如何在lte / gte比较中包含“None”?

时间:2010-10-06 23:14:52

标签: django

我有这种复杂的过滤机制......

d = copy(request.GET)
d.setdefault('sort_by', 'created')
d.setdefault('sort_dir', 'desc')
form = FilterShipmentForm(d)
filter = {
    'status': ShipmentStatuses.ACTIVE
}
exclude = {}
if not request.user.is_staff:
    filter['user__is_staff'] = False

if request.user.is_authenticated():
    exclude['user__blocked_by__blocked'] = request.user

if form.is_valid():
    d = form.cleaned_data
    if d.get('pickup_city'): filter['pickup_address__city__icontains'] = d['pickup_city']
    if d.get('dropoff_city'): filter['dropoff_address__city__icontains'] = d['dropoff_city']
    if d.get('pickup_province'): filter['pickup_address__province__exact'] = d['pickup_province']
    if d.get('dropoff_province'): filter['dropoff_address__province__exact'] = d['dropoff_province']
    if d.get('pickup_country'): filter['pickup_address__country__exact'] = d['pickup_country']
    if d.get('dropoff_country'): filter['dropoff_address__country__exact'] = d['dropoff_country']
    if d.get('min_price'): filter['target_price__gte'] = d['min_price']
    if d.get('max_price'): filter['target_price__lte'] = d['max_price']
    if d.get('min_distance'): filter['distance__gte'] = d['min_distance'] * 1000
    if d.get('max_distance'): filter['distance__lte'] = d['max_distance'] * 1000
    if d.get('available_on'): # <--- RELEVANT BIT HERE ---
        filter['pickup_earliest__lte'] = d['available_on'] # basically I want "lte OR none"
        filter['pickup_latest__gte'] = d['available_on']
    if d.get('shipper'): filter['user__username__iexact'] = d['shipper']

order = ife(d['sort_dir'] == 'desc', '-') + d['sort_by']

shipments = Shipment.objects.filter(**filter).exclude(**exclude).order_by(order) \
    .annotate(num_bids=Count('bids'), min_bid=Min('bids__amount'), max_bid=Max('bids__amount'))

现在我的客户告诉我,他希望提货/送货日期是“灵活的”选项。所以我已经更新了数据库,为此目的允许日期为NULL,但现在“可用于拾取”过滤器将无法按预期工作。它应该包括NULL / None日期。对此有一个简单的解决方法吗?

3 个答案:

答案 0 :(得分:10)

翻转逻辑并使用{​​{1}}。您真正想要做的是排除任何指定不适合的日期的数据。如果exclude()pickup_latestpickup_earliest,则它不应与排除查询匹配,也不会被删除。例如

NULL

答案 1 :(得分:3)

大多数数据库引擎不喜欢与NULL值进行关系比较。使用<field>__isnull明确检查数据库中的值是否为NULL,但您需要同时使用Q objects OR个条件。

答案 2 :(得分:0)

不要认为这实际上是一个特定于django的问题。变量'd'是python字典,不是吗?如果是这样,你可以使用它:

filter['pickup_latest__gte'] = d.get('available_on', None)