如何使用count()获取特定日期之间的项目
通过这段代码,我可以获取所有与Article
相关的orders
项目,但这里有个问题,我想要获取在两个日期之间的orders
数量,这两个日期是根据指定的timestamp
来确定的。我该怎么做呢?
class Order(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(User, on_delete=models.CASCADE,related_name='ordersauthor')
article = models.ForeignKey(Article, null=True, blank=True, on_delete=models.CASCADE,related_name='ordersarticle')
timestamp = models.DateTimeField(auto_now_add=True)
total_price = models.FloatField(default='0', validators=[MaxValueValidator(99999999999999999999)])
class ArticleSerializer(serializers.ModelSerializer):
orders = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Article
fields = '__all__'
def get_orders(self, language):
return language.ordersarticle.count()
初始输出:
{
.....,
"orders": 4, // All orders
},
期望输出:
{
.....,
"orders": 1, // Orders between 4th and 11th of march (Example)
},
更新:
class ArticleViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
queryset = Article.objects.all().order_by('-timestamp')
serializer_class = ArticleSerializer
filter_backends = [filters.SearchFilter,DjangoFilterBackend]
pagination_class = StandardResultsSetPagination
search_fields = ['^articlechoices__item','^caption','^name']
filterset_fields = ['author','price','location','category']
1 个回答
1
你可以使用以下方式进行筛选:
from datetime import date
class ArticleSerializer(serializers.ModelSerializer):
orders = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Article
fields = '__all__'
def get_orders(self, language):
return language.ordersarticle.filter(
timestamp__range=(date(2024, 3, 4), date(2024, 3, 7))
).count()
不过,这样做其实不太好:如果你需要序列化多个这样的Article
,那么每个项目都会产生一个查询。
我们可以提前计算这些内容,方法是:
from django.db.models import Count, Q
class ArticleViewSet(viewsets.ModelViewSet):
permission_classes = (IsAuthenticated,)
queryset = Article.objects.all().order_by('-timestamp')
serializer_class = ArticleSerializer
filter_backends = [filters.SearchFilter, DjangoFilterBackend]
pagination_class = StandardResultsSetPagination
search_fields = ['^articlechoices__item', '^caption', '^name']
filterset_fields = ['author', 'price', 'location', 'category']
def get_queryset(self, *args, **kwargs):
return (
super()
.get_queryset(*args, **kwargs)
.annotate(
num_orders=Count(
'ordersarticle',
filter=Q(
ordersarticle__timestamp__range=(date(2024, 3, 4), date(2024, 3, 7))
),
)
)
)
然后可以用以下方式进行序列化:
class ArticleSerializer(serializers.ModelSerializer):
orders = serializers.IntegerField(read_only=True, source='num_orders')
class Meta:
model = Article
fields = '__all__'
注意:通常来说,使用
settings.AUTH_USER_MODEL
[Django-doc] 来引用用户模型,比直接使用User
模型 [Django-doc] 更好。想了解更多信息,可以查看文档中的 引用User
模型 部分。
注意:
related_name=…
参数 [Django-doc] 是反向关系的名称,也就是说,从User
模型到Order
模型。在这种情况下,给它起个和正向关系一样的名字通常没有太大意义。所以你可能想考虑把这个关系改名为ordersauthor
orders
。