【问题标题】:Django filter query with date and integer带有日期和整数的 Django 过滤器查询
【发布时间】:2013-12-15 14:52:05
【问题描述】:

我尝试编写查询,其中必须显示飞机,工作寿命已结束。 模型.py

class Aircraft(models.Model):
    registration_num = models.IntegerField(primary_key=True)
    airplane_age = models.IntegerField()
    commision_day = models.DateField() 

Views.py

def query1(request):
    air_list = Aircraft.objects.filter(commision_day__year__lte=(datetime.date.today().year - 10))
    #air_list = Aircraft.objects.extra(where=['commision_day + airplane_age < CURDATE()'])
    #air_list = Aircraft.objects.extra(where=["commision_day+airplane_age<datetime.date.today()"]) F('airplane_age') year=10, month=1, day=1

数据示例

commision_day = 1995.10.05
airplane_age = 15

我尝试了很多方法,但没有一种方法有效((((
所以我需要显示 plnes 哪个委托日 + 飞机年龄 谢谢

【问题讨论】:

  • 您是否收到任何错误消息?如果有,它们是什么?
  • @itsjeyd 我尝试了许多具有不同错误的变体))因此,在上述情况下:Join on field 'commision_day' not permitted. Did you misspell 'year' for the lookup type? - 因为一起使用 __year 和 __lte 是错误的。 =)
  • 好的,我认为您可以尝试将commision_day 的值与另一个datetime.date 直接与适当的值进行比较。请参阅下面的answer

标签: django python-3.x django-models


【解决方案1】:

您可以尝试设置一个datetime.date 对象作为阈值,然后直接按日期过滤Aircraft 对象:

today = datetime.date.today()
threshold = datetime.date(today.year-10, today.month, today.day)
Aircraft.objects.filter(commision_day__lte=threshold)

【讨论】:

  • 此方法不适用于“airplane_age”字段。但是你给我一个好主意!我写了这个,它的工作:today = datetime.date.today() air_list = Aircraft.objects.all() for air in air_list: threshold = datetime.date(today.year - air.airplane_age, today.month, today.day) if air.commision_day &lt;= threshold: air_list = air_list.filter(registration_num__gt=air.registration_num) 格式化:pastie.org/8554147
【解决方案2】:

试试这个查询集:

from datetime import datetime, timedelta

Aircraft.objects.filter(commision_day__lte=(datetime.now() - timedelta(years=10)))

【讨论】:

  • 谢谢你的回答,但我在问之前试过这个。 datetime.timedelta() 没有参数 yearsTimedelta.=(
  • 你是对的,对不起..也许你可以用relativedelta代替timedelta..
【解决方案3】:

这里的目标是结合两个字段的值,并将结果与​​当前过程中计算的值进行比较,本质上是:

Aircraft.objects.extra(where=['somedate + years < today'])

where=['...'] 中的表达式必须是有效的 SQL,并且正确的语法取决于您的数据库后端。也就是说,您需要知道将年份添加到日期以正确形成 somedate + years 的正确方法,例如在 SQLite 中它会是这样的:

date(commision_day, '+' || airplane_age || ' year') < date('now') 

这比your solution 更有效,但它不可移植,因为由于日期操作的非标准语法,它依赖于数据库后端。

【讨论】:

  • 谢谢你的回答,但是这个方法报错Can't convert 'int' object to str implicitly
  • 已修复,请参阅我的更新答案(将年份包装在 str(...) 中)
  • operator does not exist: date &lt; integer =(
【解决方案4】:

试试这个:

from dateutil.relativedelta import relativedelta
from django.db.models import F


Aircraft.objects.filter(commision_day__lte=datetime.now()-relativedelta(years=F('airplane_age')))

【讨论】:

  • 这将引发:TypeError: int() argument must be a string, a bytes-like object or a number, not 'F'
猜你喜欢
  • 1970-01-01
  • 2019-08-15
  • 2013-08-16
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 2017-09-24
相关资源
最近更新 更多