Reputation: 81
In models:
class Match(models.Model):
user = models.ManyToManyField(User, blank=True)
hot_league = models.ManyToManyField('HotLeague', blank=True)
class HotLeague(models.Model):
user = models.ManyToManyField(User, blank=True)
price_pool = models.IntegerField()
winner = models.IntegerField()
In views:
match = Match.objects.filter(user=request.user)
hot_league = match.hot_league.filter(user=request.user).count()
Here in views count()
is not working.
How can I count the hot_league
which situated in match
??
Upvotes: 1
Views: 77
Reputation: 477883
The problem here is that match
is not a Match
object, it is a QuerySet
that contains zero, one, or more Match
objects. Therefore you can not use the hot_league
relation on such QuerySet
.
If you want to count all the HotLeague
s that belong to the request.user
, and have a Match
that belongs to that request.user
as well, you can count this as:
HotLeague.objects.filter(user=request.user, match__user=request.user).count()
This will count the same HotLeague
multiple times if it belongs to multiple matches with request.user
as user
. If you wish to count each HotLeague
only once, you can add a .distinct()
[Django-doc] to it:
HotLeague.objects.filter(user=request.user, match__user=request.user).distinct().count()
Or you can annotate the number the Match
es with the number of HotLeague
s by that user, like:
from django.db.models import Count, Q
matches = Match.objects.filter(user=request.user).annotate(
nhotleagues=Count('hotleague', filter=Q(hotleague__user=request.user))
)
Each Match
that originates from this queryset, will have an extra attribute nhotleagues
that specifies the number of HotLeague
s of that user. So you can render this like:
{% for match in matches %}
{{ match.pk }}: {{ match.notleagues }}<br>
{% endfor %}
You can sum up counts, like:
from django.db.models import Count, Q
matches = Match.objects.filter(user=request.user).annotate(
total=Count('hotleague', distinct=True, filter=Q(hotleague__user=request.user)) +
Count('mega_league', distinct=True, filter=Q(megaleague__user=request.user)) +
Count('head_to_head_league', distinct=True, filter=Q(head_to_head_league__user=request.user))
)
Although of course, the more tables you add in a JOIN, the more expensive the query will be.
Upvotes: 1