Как использовать функцию 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 the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.


Note: The related_name=… parameter [Django-doc] is the name of the relation in reverse, so from the User model to the Order 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 the ordersauthor relation to orders.

Вернуться на верх