/ / Django-Modelle: Aggregieren Sie nicht direkt verwandte Modelle - Django, Django-Modelle

Django-Modelle: Aggregiere über nicht direkt verwandte Modelle - Django, Django-Modelle

Ich habe folgende Modelle:

class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
some_field = models.CharField(max_length=100)


class UserRating(models.Model):
subject_user = models.ForeignKey(User, related_name="rated_user", on_delete=models.CASCADE)
rating_user = models.ForeignKey(User, related_name="rating_user", on_delete=models.CASCADE)
rating = models.IntegerField()

class Meta:
unique_together = ("subject_user", "rating_user")

Ich versuche, ein Abfrageset aller UserProfiles mit kommentiertem Durchschnittswert der Bewertung im UserRating-Modell zu erhalten.

Ich habe versucht, folgendes zu tun:

    queryset = UserProfile.objects.all()
for profile in queryset:
user = profile.user
ratingset = UserRating.objects.filter(subject_user = user).values_list("rating")
if len(ratingset) == 0:
profile.rating = 0
else:
profile.rating = sum(ratingset) / float(len(ratingset))

Dies wirft jedoch den folgenden Fehler ab:

TypeError: unsupported operand type(s) for +: "int" and "tuple"

Ich dachte darüber nach, die Summe zu berechnen, indem ich über Ratingset iteriere, aber mein Ansatz erscheint mir als übertrieben. Gibt es einen einfacheren Weg, um dies zu erreichen?

Antworten:

0 für die Antwort № 1

Django bietet tatsächlich verschiedene Methoden zum direkten Aggregieren über SQL, was wesentlich effizienter ist. Dies sollte die Arbeit erledigen:

profiles_with_ratings = UserProfile.objects.annotate(rating=Avg("user__rated_user__rating"))

Dokumente hier: https://docs.djangoproject.com/en/2.0/topics/db/aggregation/

Randbemerkung: Was Sie tatsächlich haben, ist eine sehr viele Beziehung zwischen Benutzern, die Sie aus irgendeinem Grund manuell erstellen.