python - 另一个表的字段返回计数
问题描述
我需要该read_books
字段(在已购买),返回Rating
对象计数。
Rating
应根据同一用户中每本书的相同集合的过滤器返回对象的数量。
我不知道该怎么做,因为Rating
并且Purchased
不直接依赖。
评级/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)
书/模型.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)
集合/models.py
class Collection(models.Model):
title = models.CharField(max_length=50)
creator = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING)
购买的_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)
应用@ruddra 的回复后
第一个选项:
def read_books(self):
return Rating.objects.filter(user=self.user, book__collection=self.collection).count()
曾在models.py
. 但是我想只有在用户登录时才运行这个功能。所以我试图把它放在def login (request):
views.py中,但是,它不是基于a的class
,我不能使用(self)。总是返回错误name 'self' is not defined.
所以,我尝试了第二个@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)
视图.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')
但永远返回错误:NameError: name 'collection__books__rating__user' is not defined.
问题是能够ratings
按自己的方式过滤每个对象collection
。在其中使用 (self)models.py
可以完美地工作,但没有 (self) 我无法使其工作。
仅在用户登录时才运行此计数的任何其他建议?
解决方案
假设您的意思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, Q
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)
推荐阅读
- android - 具有两种自定义颜色的 ActonBar
- html - 在响应式导航中,第一个元素不会显示在 img 下方
- python - 忽略第三方模块中的 logging.basicConfig
- powershell - Powershell循环遍历文件夹移动文件,如果不存在则创建目录
- android - 影响应用性能的多个 NetworkCallback 事件 (onAvailable)
- cmake - 使用 vcpkg 时如何包含 OpenCV 的 cv::VideoWriter?
- javascript - 嵌套引用的猫鼬过滤器
- javascript - 更新本地和父状态会导致未安装组件错误
- python - 如何在不使用“追加”的情况下使用 python 将脚本的“打印”发送到列表中?
- javascript - 如何使用按键角 9 选择下拉值