Метод сложных фильтров в django
Я столкнулся с проблемой, когда мне нужно отправить остатки писем всем пользователям, у которых срок обучения истекает в определенный период времени, например, в соотношении 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(), но не могу понять, как решить этот запрос. Если кто-то может помочь мне или предложить что-то полезное, я буду благодарен. Спасибо
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()