【问题标题】:Django - modify a field value just for filtering purposeDjango - 仅出于过滤目的修改字段值
【发布时间】:2021-09-28 23:25:52
【问题描述】:

我想修改some_date_field 值只是为了过滤。 就像使用 models.Lookupmodels.Transform 但我不想制作原始的 sql 表达式。

例如,使用原始的 ms sql 表达式,我可以编写:

WHERE CONVERT(date, FORMAT(some_date_field, '2021MMdd')) >= @some_var

但是我如何用 Django 做到这一点?

class SomeModel(models.Model):
    some_date_field = models.DateField()

def replace_year(value):
    return value.replace(year=2021) 

SomeModel.objects.filter(
    # replace_year(some_date_field)__gte=some_var
)

有可能吗?

【问题讨论】:

    标签: django


    【解决方案1】:

    您可以使用 SomeModel.objects.filter({whatever you want to filter}).update(some_date_field={date_value})

    如果您有任何问题,请参阅: https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.update

    【讨论】:

    • 抱歉我的不准确。我的意思是我不想更新数据库。我想为过滤器自定义字段的值。例如,在原始 SQL 中,我可以执行“where dateadd(day, 1, some_date_field) = @some_value”
    • 如果我从上面的评论中正确理解了你,你想“过滤第二天是今天的所有记录”。所以你正在寻找具有昨天日期的记录。为此你可以只使用带有 datetime 和 timedelta 的常规过滤器: from datetime import datetime, timedelta昨天 = datetime.utcnow() - timedelta(days=1) SomeModel.objects.filter(some_date_field__gt=yesterday) 将为您带来第二天所在的所有对象今天或更晚。如果您希望第二天是今天或更早,您可以将 gt 切换为 lt。
    • 所以据我所知,我无法按照自己的意愿转换条件的左侧?我可以只使用默认的简单方法,例如 __year __gte 等?
    • 如果我有 birth_date 字段并且我想显示“未来 7 天内的所有生日”怎么办。所以我想将出生年份转换为当前年份,然后使用__range。 filter() 怎么办?
    • 没错,filter 是一个需要 QuerySet(django 对象)的函数。您可以在此处查看构建 QuerySet 的所有现有方法:docs.djangoproject.com/en/3.2/ref/models/querysets 对于您的第二条评论 - 必须像这样组合 gt 和 lt 函数: SomeModel.objects.filter(birth_date__gt=today,birth_date__lt=today+timdelta(days= 7))
    【解决方案2】:

    如果您尝试批量更新查询集返回的所有对象并且您使用的是 Django 2.2 或更高版本,则可以使用“bulk_update”。

    请看这里:Django Bulk Update

    如果您根据另一个字段动态更新值,请查看 F 表达式,它们可以与查询集上的“更新”一起使用。

    请看这里:Update dynamically with F expressions

    需要注意的是,这不会使用 ModelClass.save 方法(所以如果你有一些逻辑,它不会被触发)。

    看看these answers here as well

    【讨论】:

    • 抱歉我的不准确。我的意思是我不想更新数据库。我想为过滤器自定义字段的值。例如,在原始 SQL 中,我可以执行“where dateadd(day, 1, some_date_field) = @some_value”
    【解决方案3】:

    你可以在django中使用filter()update()方法

    假设我们需要过滤一些已知年份,即 old_date 变量,新值包含在 new_date 变量中

    # defing mehod to filter and update new date
    def update_date(old_date, new_date):
        SomeModel.objects.filter(some_date_field=old_date).update(some_date_field=new_date)
        return None
    

    您可以使用 link 找到一些示例。

    希望这对你有帮助。

    【讨论】:

    • 抱歉我的不准确。我的意思是我不想更新数据库。我想为过滤器自定义字段的值。例如,在原始 SQL 中,我可以执行“where dateadd(day, 1, some_date_field) = @some_value”
    • 只是为了澄清,您只是想过滤所有年份为 2021 的记录对吗?
    • 否,例如"过滤第二天是今天的所有记录"
    • 在原始 SQL 中,我可以将任何自定义函数应用于条件的左侧
    • 我觉得你可以像这样使用过滤选项,即today是一个包含你要过滤的日期的变量。 SomeModel.objects.filter(some_date_field=today)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    相关资源
    最近更新 更多