Вложение сериализатора по годам, затем по месяцам
class Transactions(models.Model):
id = models.CharField(max_length=100, primary_key=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
date = models.DateField()
watch = models.CharField(max_length=100)
purchase_price = models.IntegerField()
sale_price = models.IntegerField()
В моей модели Transactions есть поле даты, цена покупки и цена_продажи.
@api_view(['GET'])
@permission_classes([IsAuthenticatedOrReadOnly])
def profit_chart(request):
current_year = datetime.now().year
queryset = Transactions.objects.filter(date__year=current_year).values(month=ExtractMonth('date'),
year=ExtractYear('date')).annotate(
profit=Sum(F('sale_price')) - Sum(F('purchase_price'))).order_by('month')
serializer = ProfitChartSerializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
Мое представление сортирует транзакции по текущему году и месяцу, а затем вычисляет прибыль за этот месяц.
class ProfitChartSerializer(serializers.ModelSerializer):
year = serializers.IntegerField()
month = serializers.IntegerField()
profit = serializers.IntegerField()
class Meta:
model = Transactions
fields = ['year', 'month', 'profit']
Ответ, который я получил от DRF, приведен ниже.
[
{
"year": 2024,
"month": 8,
"profit": 5000
}
]
Вопрос, который я пытаюсь выяснить, заключается в том, как я могу манипулировать приведенным выше ответом, чтобы он выглядел так, как показано ниже.
[
year: 2024
data: {
month: 8
profit: 5000
}
]
Я не думаю, что это имеет большой смысл. Действительно, вы фильтруете по году:
queryset = Transactions.objects.filter(date__year=current_year)
поэтому год всех возвращенных записей будет одинаковым.
Однако вы можете настроить сериализатор с помощью:
class PartialChartSerializer(serializers.ModelSerializer):
month = serializers.IntegerSerializer()
profit = serializers.IntegerField()
class Meta:
model = Transactions
fields = ['month', 'profit']
class ProfitChartSerializer(serializers.Serializer):
year = serializers.IntegerField()
data = PartialChartSerializer(many=True)
и передаем элементы в сериализатор в виде:
from itertools import groupby
from operator import itemgetter
@api_view(['GET'])
@permission_classes([IsAuthenticatedOrReadOnly])
def profit_chart(request):
queryset = (
Transactions.objects.values(
month=ExtractMonth('date'), year=ExtractYear('date')
)
.annotate(profit=Sum(F('sale_price')) - Sum(F('purchase_price')))
.order_by('month')
)
serializer = ProfitChartSerializer(
[
{'year': k, 'data': list(vs)}
for k, vs in groupby(queryset, itemgetter('year'))
],
many=True,
)
return Response(serializer.data, status=status.HTTP_200_OK)
Note: Normally a Django model is given a singular name [django-antipatterns], so
Transaction
instead of.Transactions