我在我的项目中使用了PostgreSQL,并且有三个相关的模型:

class Timer(models.Model):
    start = models.DateTimeField()
    end = models.DateTimeField()
    task = models.ForeignKey(
        Task,
        models.CASCADE,
        related_name="timers",
    )

class Task(models.Model):
    name = models.CharField(max_length=64)
    wanted_duration = models.DurationField()
    frequency = models.ForeignKey(
        Frequency,
        models.CASCADE,
        related_name="tasks",
    )


class Frequency(models.Model):
    class TimeUnitChoices(models.TextChoices):
        DAY = "day", "day"
        WEEK = "week", "week"
        MONTH = "month", "month"
        QUARTER = "quarter", "quarter"
        YEAR = "year", "year"

    events_number = models.PositiveIntegerField()
    time_unit = models.CharField(max_length=32, choices=TimeUnitChoices.choices
    )

我想得到一个开始的时间跨度(天,周-一个频率的值time_unit)根据start日期(计时器的字段).

我try 执行下一个代码:task.timers.annotate(start_of=Trunc('start', kind='task__frequency__time_unit'))

但是Django不接受Trunc类的kind参数中的字段.错误:psycopg.ProgrammingError: cannot adapt type 'F' using placeholder '%t' (format: TEXT)

如果我在原始SQL中执行以下查询:

SELECT
DATE_TRUNC(schedules_frequency.time_unit, timers_timer.start)::date as start_of
FROM public.tasks_task
INNER JOIN public.schedules_frequency ON tasks_task.frequency_id = schedules_frequency.id
INNER JOIN public.timers_timer ON timers_timer.task_id = tasks_task.id;

一切都如你所愿.在Django项目中是否有不直接使用原始SQL的解决方案?

推荐答案

以下代码可以正常工作:

class MyTrunc(Func):
    def as_postgresql(self, compiler, connection):
        return super().as_sql(compiler, connection, function="DATE_TRUNC")

但调用此函数时需要在传递时将种类与日期互换:

task.timers.annotate(start_of=Trunc('task__frequency__time_unit', 'start'))

I'm not sure if this implementation is vulnerable to SQL injection

Django相关问答推荐

如何在Django中更改模型字段名称?

如果密码在Django中未被散列,则对其进行散列

我的Django终结点不访问HAS_OBJECT_PERMISSION方法

Django基于查询集动态筛选字段名称

如果字段为空,则 Unique_together 不起作用.怎么约束呢?

Django:创建一个动态侧边栏模板并在其他模板中使用它

Django 如何知道我的数据库的路径?

为什么我的搜索功能返回错误相关字段查找无效:​​类别

未为部署的 django rest 框架加载静态文件

Django 视图 - 首先从调用应用程序的目录加载模板

Django App 配置不当 - 应用程序模块有多个文件系统位置

magic有什么问题?

Python/Django:从 values_list() 创建一个更简单的列表

从基于类的通用视图中获取 request.session

Django表单集:首先需要?

现在如何在 Django 中处理每个对象的权限?

登录后django重定向不起作用next不发布?

Django - 安装 mysqlclient 错误:需要 mysqlclient 1.3.13 或更高版本;你有 0.9.3

如何在 Django 中创建一个非空的 CharField?

Django 在 css 文件中使用背景图像的方法