【问题标题】:complex filters method in djangodjango 中的复杂过滤器方法
【发布时间】:2022-11-30 17:55:01
【问题描述】:

我遇到了一个问题,我需要向所有培训在某个时间段(如 5/6 的比例)内到期的用户发送剩余电子邮件。我已经设置了一个调度系统,它将过滤所有每天到期的培训计划并将剩余的发送给他们。我面临的问题是我无法弄清楚查询。

这是我正在使用的模型:

class Training(models.Model):

    class Meta:
        ordering = ('-pk',)

    uuid = models.UUIDField(default=uuid.uuid4, editable=False)
    customer = models.ForeignKey('customer.Customer', on_delete=models.CASCADE, related_name='trainings')
    name = models.CharField(max_length=512)
    presentation = models.FileField(upload_to='trainings')
    data = models.JSONField()
    description = models.TextField(default='', blank=True)
    released = models.BooleanField(default=False)
    start_at = models.DateField()
    end_at = models.DateField()
    codes_file = models.FileField(null=True, max_length=1024)
    contact = models.EmailField(blank=True)
    is_archived = models.BooleanField(default=False)
    is_reminded = models.BooleanField(default=False)

这是我要运行的查询。

trainings = Training.objects.filter(is_reminded=False, ).annotate(
    deadline=(datetime.today() - F('start_at')).days / (F('start_at') - F('end_at')).days, output_field=DateField()
).filter(deadline__gt=0.833)

我从中得到的错误。我明白为什么会出现这个错误,但我不知道如何提取这些数据。

Internal Server Error: /testing/
Traceback (most recent call last):
  File "C:\Users\HP\.virtualenvs\apaa_backend-tCJa5vIy\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\HP\.virtualenvs\apaa_backend-tCJa5vIy\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\HP\.virtualenvs\apaa_backend-tCJa5vIy\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\HP\.virtualenvs\apaa_backend-tCJa5vIy\lib\site-packages\rest_framework\viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\HP\.virtualenvs\apaa_backend-tCJa5vIy\lib\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\HP\.virtualenvs\apaa_backend-tCJa5vIy\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\Users\HP\.virtualenvs\apaa_backend-tCJa5vIy\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "C:\Users\HP\.virtualenvs\apaa_backend-tCJa5vIy\lib\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\Users\HP\Desktop\apaa_backend\apaa\testing.py", line 22, in list_deadline_trainings
    deadline=(datetime.today() - F('start_at')).days / (F('start_at') - F('end_at')).days, output_field=DateField()
AttributeError: 'CombinedExpression' object has no attribute 'days'

我尝试了不同的解决方案来解决这个问题,比如使用 F() 注释一个新列,但无法弄清楚如何解决这个查询。如果有人可以帮助我或提出有用的建议,我将不胜感激。谢谢

【问题讨论】:

    标签: python-3.x django django-models django-rest-framework orm


    【解决方案1】:

    F 表达式引用数据库中的数据并由数据库计算。它们不是 Python。

    您也许可以使用Extract,但是一个真正复杂的查询集是否值得付出努力?

    如果 Training 表的大小足够小或要提醒的分数足够大,请在查询集中执行您可以进行的过滤,其余的在 Python 中执行。

    trainings = Training.objects.filter(is_reminded=False, )
        # maybe also filter end_at not in the past, start_at not in the future?
    for training in trainings:
        deadline = (datetime.today() - training.start_at).days / (
            (training.start_at - training.end_at).days
        if deadline > 0.833:
            #do remind for this training
            training.is_reminded = True
            training.save()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 2018-01-16
      • 2011-02-06
      • 2016-06-21
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      相关资源
      最近更新 更多