【问题标题】:Django filter based on custom function基于自定义函数的 Django 过滤器
【发布时间】:2018-01-20 06:53:47
【问题描述】:

我有一个表 AvailableDates,其中有一列 date 用于存储日期信息。 我想在对日期执行一些操作后过滤日期,该操作由 convert_date_to_type 函数定义,该函数采用用户提供的参数 input_variable。

def convert_date_to_type(date,input_variable):
   #perform some operation on date based on input_variable
   #return value will be a type, which will be any one item from types list below
   return type

类型列表:

types = []
types.append('type1')
types.append('type2')
types.append('type3')

现在我想根据类型过滤表格。我将在 for 循环中执行此操作:

for i in range(0,len(types)):
   #filter table here based on types[i], something like this
   AvailableDates.objects.filter(convert_date_to_type(date,input_variable)=types[i])

我怎样才能做到这一点?非常感谢任何其他方法。

我无法将type信息存储在单独的列中,因为根据用户给出的input_variable,一个日期可以是不同的类型。

【问题讨论】:

    标签: python django django-models django-queryset django-filters


    【解决方案1】:

    您采用的方法将导致非常耗时的查询,因为您正在遍历所有对象并因此跳过所有 数据库系统在查询方面提供的时间优势。

    您必须回答的主要问题是“此查询的使用频率如何?”

    如果会很多,那么我会建议以下方法。

    1. 创建与您的模型具有一对一关系的额外列或表
    2. 覆盖模型的保存函数以处理您的日期并将结果存储在保存模型时在步骤 1 中创建的这个额外列中。
    3. 在第 1 步中创建的这个额外列上实现您的查询。

    这种方法有空间开销,但它会使查询更快。

    如果不是很多,但是查询会使您的网络请求明显变慢,那么也可以使用上述方法。它将有助于提供流畅的网络体验。

    【讨论】:

    • 以上所有步骤都可以按照django的文档轻松编码。
    • 对不起,我错过了日期可以是不同类型的部分,基于用户给出的一些 input_variable,所以我不能只有一个列来存储类型信息。我已经更新了问题。
    • 为了避免每次查询时从头计算这些类型,您必须找到一种方法将结果存储在数据库中。这就是您可以加快查询速度的方法。
    • 如果 input_variable 的返回类型是固定的,并且 input_variable 只能是有限集中的值,那么您可以在额外表中创建这些映射。唯一的区别是这个额外的表将与 AvailableDates 具有多对一的关系。现在,您可以根据给定的 input_variable 构建查询
    • 这个方法我已经想到了,如果没有别的办法我就用它。
    【解决方案2】:

    一种解决方案是先获取 ids 列表:

    dates_, wanted_ids = AvailableDates.objects.all(), []
    
    for i in range(0, len(types)):
        wanted_ids += [d for d in dates_ if convert_date_to_type(d.date) == types[i]]
    
    wanted_dates = AvailableDates.objects.filter(id__in=wanted_ids)
    

    性能不是很好,但可以工作

    【讨论】:

    • 同意,但这将是一个巨大的性能开销,因此无法实现。
    • 并不是很大的性能开销。 dates_ 已缓存,您也可以对其进行过滤,并且您只会执行一次 filter() 与每个循环中的代码不同。唯一的就是内存中的列表,但这也是可以解决的
    猜你喜欢
    • 2016-07-01
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 2011-08-06
    • 2021-06-21
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    相关资源
    最近更新 更多