【问题标题】:Unable to filter a queryset by using year and month无法使用年和月过滤查询集
【发布时间】:2020-02-23 10:11:47
【问题描述】:

我的模型是:

class Procedure(models.Model):
    procid = models.AutoField(primary_key=True, unique=True)
    timestr = models.DateTimeField(default=timezone.now)
    template = models.ForeignKey(ProcedureTemplate, on_delete=models.CASCADE, blank=True, null=True)
    clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE)
    doctor = models.ForeignKey(doctor, on_delete=models.SET_NULL, blank=True, null=True)
    customer = models.ForeignKey(customer, on_delete=models.CASCADE, null=False)

我正在尝试在模型属性上按年和月过滤查询集。

如果我按年份过滤:

procedures = Procedure.objects.filter(clinic = clinicobj, timestr__year=2020)
for proc in procedures:
    print(f'{proc.pk} {proc.timestr}')

我明白了:

66 2020-01-08 12:38:37.237585+00:00
67 2020-01-11 15:40:00.344492+00:00
68 2020-01-12 04:50:56.190794+00:00
69 2020-01-26 05:58:36.962205+00:00
70 2020-01-29 09:51:59.038017+00:00
71 2020-02-01 14:24:18.921779+00:00
72 2020-02-09 06:20:30.993496+00:00
73 2020-02-15 10:23:09.068201+00:00
74 2020-02-15 14:04:29.368066+00:00
75 2020-02-16 06:25:09.702327+00:00
76 2020-02-19 14:05:19.369457+00:00
77 2020-02-20 11:13:35.934392+00:00

但是,当我尝试通过添加月份来缩小范围时,我没有得到任何结果。这里有什么问题?

Procedure.objects.filter(clinic = clinicobj, timestr__year=2020, timestr__month=2)

<QuerySet []>

Procedure.objects.filter(clinic = clinicobj, timestr__year=2020).filter(clinic = clinicobj, timestr__month=2)

<QuerySet []>

【问题讨论】:

  • 你能分享你的模型吗?
  • @kamilyrb 我已经分享过了。
  • 我认为月份需要一个前导零。试试timestr__month='02'
  • 您可以将此行添加到您的 settings.py 并重试吗? USE_TZ = 假
  • 我可以测试。但我的应用确实需要时区。添加前导零没有帮助。

标签: python django python-3.x


【解决方案1】:

取决于文档

“当 USE_TZ 为 True 时,日期时间字段在过滤前转换为当前时区。这需要在数据库中定义时区。”

所以如果你使用mysql,你可以安装pytz并用mysql_tzinfo_to_sql加载时区表。

您也可以在 django 中关注databases document。希望对您有所帮助。

【讨论】:

    【解决方案2】:

    切换到使用Extract*,并建议检查用于保存日期时间值的时区。

    使用 USE_TZ = True。使用 (timezone.make_aware(value)) 转换日期时间

    from django.db.models.functions import ExtractMonth, ExtractYear
    
    
    procedures = (
        Procedure.objects
        .annotate(
            year=ExtractYear('timestr'), 
            month=ExtractMonth('timestr'),
        )
        .filter(
            clinic=clinicobj, 
            year=2020, 
            month=2,
        )
    )
    for proc in procedures:
        print(f'{proc.pk} {proc.timestr}')
    

    结果

    71 2020-02-01 14:24:18.921779+00:00
    72 2020-02-09 06:20:30.993496+00:00
    73 2020-02-15 10:23:09.068201+00:00
    74 2020-02-15 14:04:29.368066+00:00
    75 2020-02-16 06:25:09.702327+00:00
    76 2020-02-19 14:05:19.369457+00:00
    77 2020-02-20 11:13:35.934392+00:00
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      • 2014-02-12
      • 2019-09-30
      • 1970-01-01
      • 2019-07-27
      • 2017-07-12
      相关资源
      最近更新 更多