【问题标题】:how to get average of two date fields如何获得两个日期字段的平均值
【发布时间】:2022-01-26 18:04:28
【问题描述】:

我想减去创建用户结果对象的时间和用户注册的时间。 这些是我的模型:

class User(AbstractUser):
    id = models.AutoField(primary_key=True)
    created_at = models.DateTimeField(auto_now_add=True)
    username = models.CharField(unique=True, max_length=13)
    first_name = models.CharField(max_length=32, null=True, default=None)
    last_name = models.CharField(max_length=64, null=True, default=None)

class Results(models.Model):
    quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    created = models.DateField(auto_now_add=True, blank=True, null=True)
    score = models.FloatField()

在我看来,我想要这样的东西:(所有 Results.created 日期的总和 - 所有 User.created_at 日期的总和)/ len(所有用户)。我怎样才能做到这一点?

我使用聚合来编写这行代码进行测试:

Results.objects.filter(user__is_staff=False, user__role='applicant').aggregate(Avg(F('created')))

但它给了我这个错误:

You cannot use Sum, Avg, StdDev, and Variance aggregations on date/time fields in sqlite3 since date/time is saved as text.

【问题讨论】:

  • 你应该使用aggregate()方法(see docs
  • 我编辑了我的问题。我使用了这个聚合,但它给了我一个错误,请参阅问题

标签: django


【解决方案1】:

我假设您正在计算用户帐户创建日期与每个测验完成日期之间的平均差异。假设我们有三个结果:

  1. 用户 A 在创建帐户 3 天后完成了测验。
  2. 用户 A 在创建帐户 4 天后完成了第二次测验。
  3. 用户 B 在创建帐户 5 天后完成了一次测验。

计算将是 3、4 和 5 的平均值。

您可以使用Django's query expressions 完成此操作。

  1. 为提高准确性,请将Results 中的created 字段更改为DateTimeField 而不是DateField。否则,您的计算将不会考虑部分天数。
  2. 使用F函数引用你想要的字段:F('created')Result的创建日期,F('user__created_at')Result对应的User的帐户创建日期日期。
  3. 使用Func创建一个JulianDay类,代表SQLite的JulianDay函数。这个功能让你find the number of days between two dates
  4. 计算Avg 聚合,使用FloatField() 作为输出字段的数据类型。 (注意:将Results 中的created 字段更改为DateTimeField 后,您可以删除output_field=FloatField() 部分。)
# Import your models
from question70860461.models import User, Quiz, Results

# Import Django query expressions
from django.db.models import F, Func, FloatField, Avg

# Set up some example objects
u = User(username='jeffb', first_name='Jeff', last_name='Booth')
u.save()

q = Quiz()
q.save()

r = Results(quiz=q, user=u, score=100)
r.save()

r2 = Results(quiz=q, user=u, score=200)
r2.save()

# The usual trick to find the days between two dates on SQLite
# is to use the JulianDay function. Create a Django Func wrapper
# for this function:
class JulianDay(Func):
    function='JulianDay'

# Run a query that finds the average
# time between User creation and Results creation.
x = Results.objects.aggregate(
      result=Avg(JulianDay(F('created')) - JulianDay(F('user__created_at')),
             output_field=FloatField()))

【讨论】:

  • 我做了所有这些,但它仍然给我这个错误:class JulianDay(Func): function='JulianDay'
  • @Sam 您能否将完整的错误消息粘贴到您的评论中?这在我的 Python manage.py shell 中对我有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
相关资源
最近更新 更多