【问题标题】:Django filter based on retrieved values基于检索值的 Django 过滤器
【发布时间】:2015-09-15 07:36:15
【问题描述】:

我有一个模型,其中包含一些参数,如下所示

{ "user_name" : "john",
  "enter_time" : 1442257970.509184,
   "frequency" : 30
}

我需要编写一个过滤函数,最好使用 django-filter 或任何其他 pythonic 方式,这样我就可以过滤掉那些在

中的记录
def test():
 cur_time = time.time() 
 if cur_time >= enter_time + frequency:
  return True
 return False

目前在我的 views.py 中,我能够根据名称和单个值进行过滤。 例如,

records = UserRecord.objects.filter(token=user_token, user_name=name, status='active').distinct()
serializer = RecordSerializer(records, many=True)

我不确定,如何根据 test() 中定义的测试条件进行过滤。一种解决方法是获取 serializer.data 并处理 OrderedDictionaries 列表以过滤掉内容。但我正在寻找 django 的方法。

【问题讨论】:

    标签: python django django-filter


    【解决方案1】:

    您可以use F expressions in filters。在你的情况下:

    UserRecord.objects.annotate(time_plus_freq=F('enter_time')+F('frequency'))\
        .filter(time_plus_freq__lt=cur_time)
    

    这种过滤方式是在 SQL 中完成的,你不需要在 Python 端做任何事情。

    如果 Django 在定义带注释的表达式的类型时遇到问题,请查看注释中的 output_field kwarg

    【讨论】:

    • 我试过这样做,我收到 django 错误“表达式包含混合类型。您必须设置 output_field”
    • enter_time 和 frequency 分别是 Float 和 Int。我在定义模型时没有使用日期时间格式。
    • 哎呀我的错。我已将频率和 enter_time 都设置为 models.FloatField 。现在好像还好。
    【解决方案2】:

    如果你真的真的想直接做,有一种方法,但它会在应用程序级别完成,而不是在数据库级别。您可以像这样简单地制作生成器:

    records = (record for record in records if test(record))
    

    但这真的很糟糕,你应该避免它。

    更好的解决方案是重写您的测试条件,因此它将使用 django 查询集过滤,就像 Ivan 的回答中提到的那样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-18
      • 2020-10-30
      • 1970-01-01
      • 2020-10-28
      • 2012-09-01
      • 2018-10-09
      • 2021-11-28
      相关资源
      最近更新 更多