问题
I have 4 models:
class Platform(models.Model):
name = models.CharField(max_length=10)
class Streamer(models.Model):
name = models.CharField(max_length=50)
class Account(models.Model):
name = models.CharField(max_length=50)
streamer = models.ForeignKey(Streamer, on_delete=models.CASCADE)
platform = models.ForeignKey(Platform, on_delete=models.CASCADE)
class Stream(models.Model):
host = models.ForeignKey(Account, on_delete=models.CASCADE)
score = models.PositiveIntegerField(default=0)
There are 3 Platforms: Instagram, Twitch, and YouTube
Each Streamer has multiple accounts connected to it.
Each account can have multiple streams.
and each stream has one score.
Now lets say that for each Streamer I want to add a total score for every stream connected to every account connected to that Streamer.
I would do:
from django.db.models import Sum
Streamer.objects.annotate(total_score=Sum('account__stream__score'))
If I wanted to order each streamer by the total score I would do:
streamers = Streamer.objects.annotate(total_score=Sum('account_stream__score')).order_by('total_score')
What I'd like to do is now filter a list of Streamers by the same score but only from Accounts that have the Instagram Platform connected to it.
I'm not sure how to do this, but I would think it'd be something like this (not actual working code):
instagram_top_streamers_list = Streamer.objects.annotate(total_score_instagram=Sum(
# Somehow filter the account
'account__platform__name="Instagram"
# Then calculate the score for that one
'account__stream__score')).order_by('-total_instagram_score')
I've been looking for something related to this for hours but couldn't find an answer.
It needs to be filtered by streamers.
Again, the idea is to do the total score filter by Streamers but ONLY pull the score from Streams that are connected to a Streamer's instagram Accounts.
Hope this makes sense.
Thanks in advance!
回答1:
You can try like this(by using filter on annotation):
from django.db.models import Sum, Q
instagram_top_streamers_list = Streamer.objects.annotate(
total_score_instagram=Sum(
'account__stream__score',
filter=Q(account__platform__name='instagram'))
).order_by('-total_score_instagram')
来源:https://stackoverflow.com/questions/62952001/django-annotate-a-filtered-reverse-relationship