如何在Django中访问查询集的特定字段?

6

我在我的Django应用中有这些模型:

class Book(models.Model):
    title = models.CharField(max_length=50, unique=True)
    owner = models.CharField(max_length=30)
    price = models.DecimalField(max_digits=5, decimal_places=2, null=True)
    book_rating = models.ForeignKey('Rating', null=True)

RATE_CHOICES = zip(range(1,6), range(1,6))
class Rating(models.Model):
    user = models.ForeignKey(User)
    this_book = models.ForeignKey(Book)
    rate = models.DecimalField(max_digits=2, decimal_places=1, choices=RATE_CHOICES)
    comment = models.TextField(max_length=4000, null=True)

我试图访问每个Book模型实例的Ratings。以下是我在shell中尝试过的内容:

from django.contrib.contenttypes.models import ContentType
>>> ctype = ContentType.objects.get_for_model(Rating)
>>> ctype
<ContentType: rating>
>>> book_titles = ctype.model_class().objects.filter(this_book__title='My Test Book')
>>> book_titles
<QuerySet [<Rating: My Test Book - parrot987 - 3.0>, <Rating: My Test Book - 123@gmail.com - 5.0>]>
  1. 如何仅获取每个对象的两个评分值(5.0和3.0),而不包含其他数据?

  2. 是否可以以这样的方式完成,使我能够对数字进行平均并返回最终值?


你有很多书,每本书都有很多用户评分。是吗?如果是这样,为什么不使用ManyToMany字段呢?然后你就可以获取一本书的所有评分并计算平均分等。 - Navid Zarepak
ContentType.objects.get_for_model(Rating) 和 ctype.model_class() 是获取 Rating 的一种非常迂回的方式,而你已经导入了它。 - Paulo Almeida
2个回答

18

对于1,您可以使用(相关文档):


Rating.objects.filter(this_book__title='My Test Book').values('rate')
如果您只想要一个平面列表,可以使用values_list('rate', flat=True)而不是values('rate')
有关2的相关文档,请参见:文档
from django.db.models import Avg

Rating.objects.filter(this_book__title='My Test Book').aggregate(Avg('rate'))

这将返回一个字典,其中键为rate__avg,值为评分的平均值。


1
请参见以下内容,了解关于多对一字段的信息 django - 从多对一关系中获取对象集合 要访问评分,您可以使用for循环并访问各个值,例如。
total = 0
for rating in book_titles.book_set.all()
    total += rating.rate

祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接