Как использовать функцию count() для получения элементов между определенными датами
С помощью этого кода я могу получить все orders
элементы, которые связаны с Article
, но вот проблема, я хочу получить количество 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']
Вы можете фильтровать с помощью:
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__'
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.
Note: The
related_name=…
parameter [Django-doc] is the name of the relation in reverse, so from theUser
model to theOrder
model in this case. Therefore it (often) makes not much sense to name it the same as the forward relation. You thus might want to consider renaming therelation toordersauthor
orders
.