Ho i seguenti modelli:
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")
Sto cercando di ottenere un queryset di tutti i profili utente con valore medio annotato della valutazione nel modello UserRating.
Ho provato a fare quanto segue:
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))
Tuttavia questo genera il seguente errore:
TypeError: unsupported operand type(s) for +: "int" and "tuple"
Ho pensato di calcolare la somma ripetendo il classificatore, ma il mio approccio sembra eccessivo. C'è un modo più semplice per raggiungere questo obiettivo?
risposte:
0 per risposta № 1Django offre in realtà vari metodi per aggregare direttamente tramite SQL, che è molto più efficiente. Questo dovrebbe portare a termine il lavoro:
profiles_with_ratings = UserProfile.objects.annotate(rating=Avg("user__rated_user__rating"))
documenti qui: https://docs.djangoproject.com/en/2.0/topics/db/aggregation/
Nota a margine: ciò che effettivamente hai è una relazione molti a molti tra utenti che stai costruendo manualmente per qualche motivo.