Django在函数中传入字段时出错,Django

6ojccjat  于 2023-03-20  发布在  Go
关注(0)|答案(1)|浏览(127)

我想订购评价最高的10张专辑,但是当我通过函数“averageReview”订购时,它给了我一个字段错误,解决方案是什么?
视图:

def homeview(request):
    highest_rated = albums.objects.order_by('-averageReview')[9]
    album = albums.objects.all()
    return render(request, "home/home.html", {'albums' : album, 'highest_rated' : highest_rated })

型号:

class albums(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    release_date = models.CharField(max_length=10)
    artist = models.CharField(max_length=100)
    genre = models.CharField(choices=GENRE_CHOICES, max_length=20)
    image = models.ImageField(default='default2.jpg', upload_to='album_pics')

    @classmethod
    def averageReview(self):
        reviews = ReviewRating.objects.filter(album=self, status=True).aggregate(average=Avg('rating'))
        avg = 0
        if reviews['average'] is not None:
            avg = float(reviews['average'])
        return avg
    

    def __str__(self):
        return self.title
    
class ReviewRating(models.Model):
    album = models.ForeignKey(albums, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    subject = models.CharField(max_length=100, blank=True)
    review = models.TextField(max_length=1500, blank=True)
    rating = models.FloatField()
    ip = models.CharField(max_length=20, blank=True)
    status = models.BooleanField(default=True)
    created_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.subject or f"ReviewRating #{self.pk}"
svujldwt

svujldwt1#

Django ORM将QuerySet转换为SQL查询。数据库不知道Python/Django的任何信息,所以它不能处理属性。
您可以按注解排序,因此:

from django.db.models import Avg, F, Q

def homeview(request):
    highest_rated = (
        Album.objects.alias(
            avg_rating=Avg(
                'reviewrating__rating', filter=Q(reviewrating__status=True)
            )
        )
        .order_by(F('avg_rating').desc(nulls_last=True))
        .first()
    )
    album = Album.objects.all()
    return render(
        request,
        'home/home.html',
        {'albums': album, 'highest_rated': highest_rated},
    )

对于模型,您可以使用以下方法简化(和更正)属性:

class Album(models.Model):
    # …

    @property
    def averageReview(self):
        return (
            self.reviewrating_set.filter(status=True).aggregate(
                average=Avg('rating')
            )['average']
            or 0
        )

    def __str__(self):
        return self.title

class ReviewRating(models.Model):
    album = models.ForeignKey(Album, on_delete=models.CASCADE)
    # …

注意:通常使用**settings.AUTH_USER_MODEL[Django-doc]来引用用户模型比直接使用User*模型[Django-doc]要好。更多信息请参见文档中的 * refering the User model 部分。
注意:Django中的模型是用 PascalCase 编写的,而不是 snake_case,所以你可能需要将模型从albums重命名为Album

相关问题