python - 带有注释的 Django 查询集
问题描述
我正在 Django Manager 模型中编写一种方法。我想编写一种方法来找出每位作者所有已售出的副本(书籍)的数量。
我有两个用Manager编写的模型和方法。我的问题是该方法也应该可以从任何作者查询集中链接,例如
Author.objects.filter(...).exlucde(...).total_copies_sold()
也应该工作。
例子:
author = Author.objects.create(...)
Book.objects.create(..., author=author, copies_sold=10)
Book.objects.create(..., author=author, copies_sold=20)
author_total_books = Author.objects.total_copies_sold().first()
>>> author_total_books.copies
30
在我的代码下面。它像上面的例子一样工作,但后来我尝试了类似的东西:
author_books = Author.objects.filter(id=2).total_copies_sold()
我有
'QuerySet' 对象没有属性 'annotate'
class AuthorManager(models.Manager):
def total_copies_sold(self):
return self.get_queryset().annotate(copies=Sum('book__copies_sold')
class Author(models.Model):
first_name = models.CharField(max_length=120)
last_name = models.CharField(max_length=120)
objects = AuthorManager()
class Book(models.Model):
title = models.CharField(max_length=120)
copies_sold = models.PositiveIntegerField()
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
[已编辑]
谢谢席林特的回复。我补充说:
class AuthorQueryset(models.QuerySet):
def total_copies_sold(self):
return self.annotate(copies=Sum('books__copies_sold'))
我试过类似的东西:
author_books = Author.objects.filter(id=2).total_copies_sold()
>>> author_books.copies
我有
“AuthorQueryset”对象没有属性“副本”
解决方案
你正在寻找的是:
from django.db import models
from django.db.models import Sum
from django.db.models.functions import Coalesce
class AuthorManager(models.Manager):
def get_queryset(self):
return AuthorQuerySet(self.model, using=self._db)
def annotate_with_copies_sold(self):
return self.get_queryset().annotate_with_copies_sold()
class AuthorQuerySet(models.QuerySet):
def annotate_with_copies_sold(self):
return self.annotate(copies_sold=Sum('books__copies_sold'))
class Author(models.Model):
objects = AuthorManager()
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
class Book(models.Model):
title = models.CharField(max_length=30)
copies_sold = models.PositiveIntegerField()
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
现在可以链接查询,例如:
author_total_books = Author.objects.total_copies_sold().first()
但是,您将无法在 QuerySet 对象上使用它,例如:
author_books = Author.objects.filter(id=2).total_copies_sold()
那是因为您正在注释作者对象,而不是 QuerySet。要获得该结果,您应该执行:
Author.objects.annotate_with_copies_sold().get(id=2)
author.copies_sold
15
推荐阅读
- zfit - 2 暗数据集的 zfit 直线拟合
- swiftui - 在 SwiftUI 中使用图层自定义 Mapbox 样式
- python - 如何将字符串基数 2 作为整数?
- spring-io - 无法访问 repo.spring.io - 未经授权
- vue.js - 在heroku中部署vue应用程序的问题
- python - CSS Selector 没有提取出我想要的数据
- java - 在java中实现一个JSON对象
- node.js - npm 错误!在 myfrontend@3.3.0 构建脚本中失败
- mysql - 将数据插入和更新到由外键链接的表中
- python - 查找具有 Null 值的列并将它们写入 Pyspark 中每条记录的新列中