Django ORM Получение пользователей, которые НЕ обновляли информацию о своей зарплате за последний 1 год (Simlpe History )
Я хочу вывести пользователей, которые не обновляли информацию о своей зарплате за последний 1 год. НО С помощью ORM, а не For Loop.
from simple_history.models import HistoricalRecords
class User(AbstractUser):
...
salary_expectation = models.IntegerField()
history = HistoricalRecords(cascade_delete_history=True)
################################################################
User.objects.filter(# MAGIC ) # Get users who have NOT updated their salary information in the last year
Я вижу, что это пакет, который имеет свою документацию по запросу его записей, см. ниже: https://django-simple-history.readthedocs.io/en/latest/querying_history.html
тем не менее, вы можете сделать это интуитивно, следуя обычному поведению Django и нескольким знаниям SQL, я бы ожидал, что таблица поля history скорее всего имеет отношения один-ко-многим с таблицей users, поэтому я бы сделал следующее: сначала открыл базу данных, нашел столбец, который показывает дату изменения, записал его имя и затем написал этот ORM запрос ниже
sub_query = ~Q(history__date_column_name__lte= "Replace with end of date", history__date_column_name__gte= "Replace with beginning of date", affected_column_name="salary_expectation")
users = User.objects.filter(sub_query)
не забудьте импортировать Q
from django.db.models import Q
Вам не нужно проверять HistoricalRecords
класс на наличие этой информации.
- Добавьте поля
created_at
иupdated_at
(date_time_fields) в вашуUser
модель
class User(...):
...
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
- Код квариры
from django.db.models.functions import Now, ExtractDay
from django.contrib.auth import get_user_model
User = get_user_model()
users = User.objects.annotate(
# Calculate duration between now and last update date saved
duration=models.ExpressionWrapper(
Now() - models.F("updated_at"),
output_field=models.DurationField()
),
# Extract the amount of days in the duration
days=ExtractDay('duration'),
# Check if the number of days between the 2 fields exceeds 1 year (365.25 Days)
last_update_beyond_a_year=models.Case(
models.When(
models.Q(days__gte=365.25),
then=True
),
default=False,
output_field=models.BooleanField()
)
# Then filter
).filter(last_update_beyond_a_year=True)
и Вуаля!