我如何使我的序列化程序更具动态性

时间:2018-09-26 07:25:58

标签: python django

这是我的模特。py

from __future__ import unicode_literals
from django.db import models

class User(models.Model):
    name = models.CharField(max_length=200)
    company_name = models.ForeignKey('Company',on_delete=models.CASCADE,related_name='user')

    def __str__(self):
        return self.name

class Company(models.Model):
    name = models.CharField(max_length=200)
    phone_number = models.IntegerField(null=True,blank=True)

    def __str__(self):
        return self.name

class Catalog(models.Model):
    name = models.CharField(max_length=200)
    no_of_pcs = models.IntegerField(null=True,blank=True)
    per_piece_price = models.DecimalField(null=True,blank=True,max_digits=10,decimal_places=2)
    company_name = models.ForeignKey(Company,on_delete=models.CASCADE,related_name='catalog')

    def __str__(self):
        return self.name

这是我的serializers.py

from rest_framework import serializers
from .models import *
from django.db.models import Sum,Count

class CatalogSerializer(serializers.ModelSerializer):
    total_pieces = serializers.SerializerMethodField()
    total_price = serializers.SerializerMethodField()

    class Meta:
        model = Catalog
        fields = ('name','no_of_pcs','per_piece_price','company_name','total_pieces','total_price')

    def to_representation(self, instance):
        rep = super(CatalogSerializer, self).to_representation(instance)
        rep['company'] = {
                              "company_name":instance.company_name.name,
                              "phone_number":instance.company_name.phone_number,
                              "company_id":instance.company_name.id
                         }
        return rep

    def get_total_pieces(self, obj):
        totalpieces = Catalog.objects.aggregate(total_pieces=Count('no_of_pcs'))
        return totalpieces["total_pieces"]

    def get_total_price(self, obj):
        totalprice = Catalog.objects.aggregate(total_price=Sum('per_piece_price'))
        return totalprice["total_price"]

这是我的views.py

from __future__ import unicode_literals
from django.http import HttpResponse
from .models import *
import json
from django.http import JsonResponse, HttpResponse
from .serializers import *
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import viewsets

class CatalogView(viewsets.ModelViewSet):
    queryset =  Catalog.objects.select_related('company_name')
    serializer_class = CatalogSerializer

我如何使我的序列化程序更具动态性,而不是手动进行(粗糙方式)。 有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

当您使用serializerMethodField(**kwargs)字段时,它将计算每个项目的total_pieces和total_price,这意味着当有100个项目时,它将发送查询以计算200次。为避免这种情况,我建议您添加额外的action或使用list_route(对于其余版本的rest框架)装饰器。需要此类统计信息时,将调用此api。 示例:

class CatalogView(ModelViewSet):
    @list_route(['GET'], permission_classes=[permissions.AllowAny])
    def get_statistics(self, request):
        result = Catalog.objects.aggregate(total_pieces=Sum('no_of_pc'), total_price=Sum('per_piece_price')) # it returns dictionary such as {'total_pieces': 10, 'total_price': 1200}
        return Response(results)