【问题标题】:Add Calculated Virtual Column to Django Model Queryset将计算的虚拟列添加到 Django 模型查询集
【发布时间】:2021-03-26 08:24:13
【问题描述】:

我在尝试将虚拟列添加到我的 django 模型时遇到了困难。

我的Store 模型有以下数据库字段:

from pytz import timezone, all_timezones

TIMEZONES = tuple(zip(all_timezones, all_timezones))

class Store(models.Model):
    time_opening = models.TimeField()
    time_closing = models.TimeField()
    # 'america/los_angeles'
    time_zone = models.CharField(max_length=32, choices=TIMEZONES)

如何将is_open 字段添加到我的商店查询集的结果中?

该字段的逻辑类似于:

time_opening <= datetime.now(tz=timezone(time_zone)) <= time_closing

我曾尝试在 StoreManager 类中使用注解,但我不确定如何使用上述逻辑构造表达式。

class StoreManager(Manager):
    def get_queryset(self):
        return super().get_queryset().annotate(is_open=??????)

我还编写了原始 sql 作为备份,它根据所需的逻辑返回一个虚拟列 is_open。例如:

SELECT Store.*, True as is_open;

在这种情况下,我不确定在哪里使用我的原始 sql。我是否将它放在 StoreManager get_queryset 函数中? 我是否调用 Store.objects.raw()?如果是这样,我应该在哪里调用它?它将如何影响内置的 django 过滤和分页?

【问题讨论】:

  • from django.db.models import BooleanField, Q, ExpressionWrapper; .annotate(is_open=ExpressionWrapper(Q(time_opening__gte=datetime.now().time(), time_closingt__lte=datetime.now().time()),output_field=BooleanField()))

标签: django django-models django-rest-framework


【解决方案1】:

您可以使用以下命令注释您的 Store 对象:

from django.db.models import BooleanField, ExpressionWrapper, Q
from django.utils.timezone import now

class StoreManager(Manager):
    def get_queryset(self, *args, **kwargs):
        time = now().time()
        return super().get_queryset(*args, **kwargs).annotate(
            is_open=ExpressionWrapper(
                Q(time_opening__lte=time, time_closing__gte=time)
                output_field=BooleanField()
            )
        )

【讨论】:

    猜你喜欢
    • 2019-12-12
    • 2015-06-17
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    相关资源
    最近更新 更多