django - 我该如何注释?
问题描述
我如何为每本书注释所有已售出的书籍Author
from django.db import models
from django.db.models import Count
class AuthorQuerySet(models.QuerySet):
def annotate_with_copies_sold(self):
return Author.objects.annotate(num_copies=Count('books__copies_sold'))
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 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')
断言失败
Output (stderr):
Traceback (most recent call last):
File "/usr/local/lib/python3.6/unittest/case.py", line 59, in testPartExecutor
yield
File "/usr/local/lib/python3.6/unittest/case.py", line 605, in run
testMethod()
File "/task/assignment/tests.py", line 92, in test_annotating_works_with_filtering
"Annotating with copies sold should work well with filtering")
File "/usr/local/lib/python3.6/unittest/case.py", line 829, in assertEqual
assertion_func(first, second, msg=msg)
File "/usr/local/lib/python3.6/unittest/case.py", line 822, in _baseAssertEqual
raise self.failureException(msg)
AssertionError: 3 != 2 : Annotating with copies sold should work well with filtering
Output (stderr):
Traceback (most recent call last):
File "/usr/local/lib/python3.6/unittest/case.py", line 59, in testPartExecutor
yield
File "/usr/local/lib/python3.6/unittest/case.py", line 605, in run
testMethod()
File "/task/assignment/tests.py", line 29, in test_should_annotate
self.assertIsNotNone(Author.objects.annotate_with_copies_sold().first().copies_sold,
AttributeError: 'Author' object has no attribute 'copies_sold'
RUNTIME ERROR
解决方案
这不是一个Count
,而是一个Sum
:
from django.db.models import Sum
class AuthorQuerySet(models.QuerySet):
def annotate_with_copies_sold(self):
return Author.objects.annotate(num_copies=Sum('books__copies_sold'))
每个都Book
包含一个整数,其中包含已售出的副本数量,因此为了检索总数,您可以将这些数字与该作者所写的所有书籍相加。
对于Author
没有相关Book
s 的 s(满足过滤器),我们可以使用Coalesce
表达式 [Django-doc]:
from django.db.models import Sum, V
from django.db.models.functions import Coalesce
class AuthorQuerySet(models.QuerySet):
def annotate_with_copies_sold(self):
return Author.objects.annotate(num_copies=Coalesce(Sum('books__copies_sold'), V(0)))
推荐阅读
- javascript - Mongoose - 我的数据库复制了一个属性,而不是将新条目与旧条目合并
- php - 使用 AJAX 我想在提交后显示一条消息
- android - 模拟器:qemu-system-x86_64:警告:主机不支持请求的功能:CPUID.01H:ECX.sse4.2 [bit 20]
- android - 如何通过热点在移动应用程序中运行服务器
- python - Anaconda 3 安装 - FileNotFoundError
- javascript - 意外 [ 在循环内定义数组时
- assembly - 汇编器硬件/软件如何在 cpu 中实现?
- java - 在 Java 中删除文件的问题
- javascript - AWS Appsync graphqlMutation helper 不更新查询
- apache - Apache 服务器中特定目录中的 403/404 错误