вернет границу, превышающую ожидаемую, и вы можете напрямую использовать обратное имя для фильтрации объектов статьи, а также чрезмерное использование уникальных
осылки:
Queryset должен вернутьArticle
sQueryset должен возвращать уникальные объектыНе должен использоваться для циклов, попадающих в базу данных (имеется в виду N запросов для N объектов для аннотирования)мои модели:
class Report(BaseModel):
ios_report = JSONField()
android_report = JSONField()
class Article(BaseModel):
internal_id = models.IntegerField(unique=True)
title = models.CharField(max_length=500)
short_title = models.CharField(max_length=500)
picture_url = models.URLField()
published_date = models.DateField()
clip_link = models.URLField()
reports = models.ManyToManyField(
"Report", through="ArticleInReport", related_name="articles"
)
class ArticleInReport(BaseModel):
article = models.ForeignKey("core.Article", on_delete=models.CASCADE, related_name='articleinreports')
report = models.ForeignKey("core.Report", on_delete=models.CASCADE, related_name='articleinreports')
ios_views = models.IntegerField()
android_views = models.IntegerField()
@property
def total_views(self):
return self.ios_views + self.android_views
Все начинается сReport
объект, который создается с заданными интервалами. Этот отчет содержит данные о статьях и их соответствующих просмотров.Report
будет иметь отношения сArticle
черезArticleInReport
, который содержит общее количество пользователей вArticle
на момент импорта отчета.
На мой взгляд, мне нужно отобразить следующую информацию:
Все статьи, которые получили просмотры за последние 30 минут.Каждая статья снабжена следующей информацией, и именно здесь я сталкиваюсь с проблемой:Если количество просмотровArticle
объект имел впрошлой Report
, Если нет, 0.
мойviews.py
файл:
reports_in_time_range = Report.objects.filter(created_date__range=[starting_range, right_now]).order_by('created_date')
last_report = reports_in_time_range.prefetch_related('articles').last()
unique_articles = Article.objects.filter(articleinreports__report__in=reports_in_time_range).distinct('id')
articles = Article.objects.filter(id__in=unique_articles).distinct('id').annotate(
total_views=Case(
When(id__in=last_report.articles.values_list('id', flat=True),
then=F('articleinreports__ios_views') + F('articleinreports__android_views')),
default=0, output_field=IntegerField(),
))
Некоторое объяснение моего мыслительного процесса: во-первых, получите мне только статьи, которые появляются в соответствующих отчетах за определенный промежуток времени (filter(id__in=unique_articles)
), вернуть только отдельные статьи. Далее, если идентификатор статьи появляется впоследний отчетСписок статей (черезArticleInReport
конечно), рассчитать iOS просмотров + Android просмотров для этогоArticleInReport
.
Эта выше аннотация работает для большинстваArticle
с, но неудачно для других без видимой причины. Я пробовал много разных подходов, но, похоже, всегда получаю неправильные результаты.