Python 另一个表的字段返回计数

Python 另一个表的字段返回计数,python,django,postgresql,django-models,Python,Django,Postgresql,Django Models,我需要read\u books字段(在已购买中),返回评级对象计数 应根据评级中每本书的相同集合和同一用户的筛选器返回对象数 我不知道怎么做,因为评级和购买并不直接相关 评级/型号.py class Rating(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING) book = models.ForeignKey(Book, on_delete

我需要
read\u books
字段(在已购买中),返回
评级
对象计数

应根据
评级
中每本书的相同集合和同一用户的筛选器返回对象数

我不知道怎么做,因为
评级
购买
并不直接相关

评级/型号.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)

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)
class Collection(models.Model):
    title = models.CharField(max_length=50)
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
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)
book/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)

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)
class Collection(models.Model):
    title = models.CharField(max_length=50)
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
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)
collection/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)

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)
class Collection(models.Model):
    title = models.CharField(max_length=50)
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
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)
已购买的_collections/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)

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)
class Collection(models.Model):
    title = models.CharField(max_length=50)
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
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)
应用@ruddra的响应后

第一种选择:

    def read_books(self):
        return Rating.objects.filter(user=self.user, book__collection=self.collection).count()
models.py中工作过。但我只想在用户登录时运行此功能。
所以我试着把它放在
def login(request):
in views.py中, 但是,它不是基于
,我不能使用(self)。始终返回错误
名称“self”未定义。

因此,我尝试了secont@ruddra的建议:

purchases = Purchased.objects.annotate(read_books=Count('collection__books__rating', filter=Q(collection__books__rating__user=F('user'))))
for item in purchases:
    print(item.read_books)
views.py

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from .login import login_user

from purchased.models import Purchased
from rating.models import Rating
from collection.models import Collection
from book.models import Books

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

def login(request):
    if not request.user.is_authenticated:
        if request.method == 'POST':
            login_status = login_user(request)
            if login_status != 1:
                messages.error(request, 'Invalid')
                return redirect('login')
            else:
                messages.success(request, 'You are now logged in')

                purchases = Purchased.objects.annotate(read_books=Count('collection__books__rating', filter=Q(collection__books__rating__user=F('user'))))
                for item in purchases:
                   print(item.read_books)


                return redirect('home')

        else:
            return render(request, 'users/login.html')
    else:
        messages.error(request, 'You are already logged in')
        return redirect('index')
但始终返回错误:
name错误:未定义名称“收藏\书籍\评级\用户”。

问题在于能够按对象本身的
集合
过滤每个
评级
对象。在
models.py中使用(self)可以很好地工作,但是没有(self)我无法使它工作


如果您使用
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()

如评论中所述,如果您使用
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()

假设您的意思是
book=models.ForeignKey(book,on_delete=models.CASCADE,null=False)
in
Rating
model:

可以使用property方法返回计数:

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()
或者更好,如果您使用(这将减少数据库命中,您可以使用它进行查询):


假设您的意思是
book=models.ForeignKey(book,on_delete=models.CASCADE,null=False)
in
Rating
model:

可以使用property方法返回计数:

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()
或者更好,如果您使用(这将减少数据库命中,您可以使用它进行查询):


book=models.ForeignKey(语句,on\u delete=models.CASCADE,null=False)
它是准确的还是应该是
book=models.ForeignKey(book,on\u delete=models.CASCADE,null=False)
?是的,你是正确的。很抱歉我对它进行了编辑。
book=models.ForeignKey(语句,on\u delete=models.CASCADE,null=False)
它是准确的还是应该是
book=models.ForeignKey(book,on\u delete=models.CASCADE,null=False)
?是的,你是正确的。很抱歉我对它进行了编辑。我只是想在用户登录时运行此功能。我尝试将此函数与登录函数一起放在view.py中,但它不起作用,也没有返回任何错误。所以,它只适用于模型。当用户登录时,我可以做些什么来运行此功能?我只想在用户登录时运行此功能。我尝试将此函数与登录函数一起放在view.py中,但它不起作用,也没有返回任何错误。所以,它只适用于模型。当用户登录时,如何运行此函数?NameError:name“collection\u_statement\u_progress\u_user”未定义。怎么了?发生了同样的错误。我编辑了该问题以试图澄清情况。名称错误:未定义名称“收集\声明\进度\用户”。怎么了?发生了同样的错误。我编辑了这个问题,试图澄清情况。