Django annotate() не складывает количество записей, а вместо этого повторяет их
Фон:
<<vocab.db
Что бы я хотел делать:
Я хотел бы запросить мою таблицу KindleLookups на предмет моих самых сложных слов (например: сколько раз я искал определенное слово). В конечном итоге я хотел бы представить эти данные в виде таблицы, упорядоченной по наибольшему количеству.
Желаемый результат:
| Word | Lookup Count |
|---|---|
| Reverberated | 3 |
| Troubadour | 1 |
| Corrugated | 1 |
Мой результат (нежелательный):
Здесь Reverberated повторяется три раза с количеством просмотров по одному, вместо одного раза с тремя просмотрами.
| Word | Lookup Count |
|---|---|
| Реверберированный | 1 |
| Возвращенный | 1 |
| Возвращенный | 1 |
| Трубадур | 1 |
| Corrugated | 1 |
Модель:
class KindleLookups(TimeStampedModel):
book = models.ForeignKey(KindleBookInfo, on_delete=models.CASCADE)
word = models.ForeignKey(KindleWords, on_delete=models.CASCADE)
...
class KindleWords(TimeStampedModel):
word_key = models.CharField(max_length=255, unique=True)
word = models.CharField(max_length=255)
...
Я пытаюсь сделать это с помощью annotate(), но по какой-то причине строки повторяются, а не складываются.
context['lookup_counts'] = KindleLookups.objects.annotate(word_count=Count("word"))
Затем я подумал, что мне нужно сделать аннотацию на самом слове, но, похоже, ничего не изменилось.
context['lookup_counts'] = KindleLookups.objects.annotate(word_count=Count("word__word"))
Шаблон:
<tbody>
{% for word in lookup_counts %}
<tr>
<td>{{ word.word }}</td>
<td>{{ word.word_count }}</td>
</tr>
{% endfor %}
</tbody>
Так что я надеюсь, что вы сможете ответить на мои вопросы:
Вопросы
- What is actually happening with my annotate()? Why is it repeating the rows instead of counting them, despite me using Count()?
- Would counting on the "word" and "word__word" be the exact same thing?
- Could this issue be somehow related with my
KindleLookups's__str__method returning theself.usage(the sentence the word was found in) and not the word?
Вы должны аннотировать модель KindleWords вместо этого, так:
context['lookup_counts'] = KindleWords.objects.annotate(
word_count=Count('kindlelookups')
)
У KindleWords, возникающих из этого набора запросов, будет дополнительный атрибут .word_count, определяющий, сколько раз этот KindleWords будет использован в KindleLookups.
Примечание: обычно модели Django присваивается сингулярное имя, поэтому
KindleWordвместо.KindleWords