另一个表的字段返回计数

时间:2019-12-11 03:35:57

标签: python django postgresql django-models

我需要read_books字段(在“已购买”中),返回Rating个对象计数。

应根据Rating中每本书的相同馆藏和同一用户的过滤器返回对象数。

我不知道该怎么做,因为RatingPurchased并不直接相关。

rating / models.py

class Rating(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
    book = models.ForeignKey(Book, on_delete=models.CASCADE, null=False)
    rating = models.IntergerField(default=0)

book / models.py

class Books(models.Model):      
    collection = models.ForeignKey(Collection, on_delete=models.DO_NOTHING, blank=True, null=True)
    book = models.CharField(max_length=250, blank=True, null=True)

collection / models.py

class Collection(models.Model):
    title = models.CharField(max_length=50)
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)

purchased_collections / models.py

class Purchased(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
    collection = models.ForeignKey(Collection, on_delete=models.DO_NOTHING)
    date = models.DateTimeField(default=datetime.now) 
    read_books = models.IntegerField(default=0)

2 个答案:

答案 0 :(得分:1)

如评论中所述,如果您使用Book作为与外键相关的模型,则可以通过以下方式找出计数:

class Purchased(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
    collection = models.ForeignKey(Collection, on_delete=models.DO_NOTHING)
    date = models.DateTimeField(default=datetime.now) 
    read_books = models.IntegerField(default=0)

    def save(self):
        self.read_books = Rating.objects.filter(user=self.user, book__in=self.collection.books_set).count()
        return super().save()

答案 1 :(得分:1)

假设您在book = models.ForeignKey(Book, on_delete=models.CASCADE, null=False)模型中意为Rating

您可以使用属性方法来返回计数:

class Purchased(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
    collection = models.ForeignKey(Collection, on_delete=models.DO_NOTHING)
    date = models.DateTimeField(default=datetime.now) 

    @property
    def read_books(self):
        return Rating.objects.filter(user=self.user, book__collection=self.collection).count()

或者更好,如果您使用annotation(这将减少数据库命中率,并且可以将其用于查询):

from django.db.models import Count, F

purchases = Purchased.objects.annotate(read_books=Count('collection__books__rating', filter=(collection__books__rating__user=F('user'))))

for item in purchases:
    print(item.read_books)