mam modele:Django liczyć na wiele-do-wielu
class Article(models.Model):
title = models.TextField(blank=True)
keywords = models.ManyToManyField(Keyword, null=True, blank=True)
class Keyword(models.Model):
keyword = models.CharField(max_length=355, blank=True)
Chcę uzyskać rachubę, ile artykułów mieć każdego słowa kluczowego. W gruncie rzeczy chcę mieć listę słów kluczowych, w których każdy może policzyć, aby uzyskać względną wagę.
Próbowałem:
keyword_list=Article.objects.all().annotate(key_count=Count('keywords__keyword'))
ale
keyword_list[0].key_count
prostu wydaje mi dać numer różnych słów kluczowych każdy artykuł ma? Czy jest to w jakiś sposób odwrotne wyszukiwanie?
Każda pomoc będzie mile widziana.
UPDATE
Więc mam to działa:
def keyword_list(request):
MAX_WEIGHT = 5
keywords = Keyword.objects.order_by('keyword')
for keyword in keywords:
keyword.count = Article.objects.filter(keywords=keyword).count()
min_count = max_count = keywords[0].count
for keyword in keywords:
if keyword.count < min_count:
min_count = keyword.count
if max_count > keyword.count:
max_count = keyword.count
range = float(max_count - min_count)
if range == 0.0:
range = 1.0
for keyword in keywords:
keyword.weight = (
MAX_WEIGHT * (keyword.count - min_count)/range
)
return { 'keywords': keywords }
ale widok wyników w ohydnym liczby zapytań. Próbowałem realizować podane tu sugestie (dziękuję), ale jest to jedyny metid, który wydaje się działać w tej chwili. Jednak muszę zrobić coś złego, ponieważ mam ponad 400 zapytań!
UPDATE
wooh! W końcu dostał pracę:
def keyword_list(request):
MAX_WEIGHT = 5
keywords_with_article_counts = Keyword.objects.all().annotate(count=Count('keyword_set'))
# get keywords and count limit to top 20 by count
keywords = keywords_with_article_counts.values('keyword', 'count').order_by('-count')[:20]
min_count = max_count = keywords[0]['count']
for keyword in keywords:
if keyword['count'] < min_count:
min_count = keyword['count']
if max_count < keyword['count']:
max_count = keyword['count']
range = float(max_count - min_count)
if range == 0.0:
range = 1.0
for keyword in keywords:
keyword['weight'] = int(
MAX_WEIGHT * (keyword['count'] - min_count)/range
)
return { 'keywords': keywords}
Dlaczego to w dół głosowało, że wygląda na poprawną odpowiedź, czy coś mi brakuje? – solartic
Jest to rzeczywiście poprawna odpowiedź, ale prawdopodobnie użyłby trochę wyjaśnienia. – jathanism
Możesz uprościć go do 'Keyword.objects.all(). Adnotate (Count ('article')) [0] .article__count' – guival