计数并分组

时间:2019-07-13 09:54:22

标签: django django-rest-framework

我想计算car_number分组的country字段中的记录数。

我的模型。py

class country(models.Model):
    country_name = models.CharField(max_length=50, blank=True, default="none")
    volgorde = models.PositiveIntegerField(blank=True, null=True)
    def __str__(self):
        return self.country_name

class car(models.Model):
    car_number = models.CharField(verbose_name='VIN',max_length=11,unique=True,blank=False ,validators=[numeric])
    car_country = models.ForeignKey('country', verbose_name='Country',blank=True, null=True, default=1, on_delete=models.PROTECT)

    def __str__(self):
        return (self.car_number)

    def get_absolute_url(self):
        return reverse("car:list", kwargs={"id":self.id})

    class Meta:
        ordering = ["-car_number"]

我的views.py

class CarViewSet(viewsets.ModelViewSet):
    queryset =  car.objects.only('car_country').select_related('car_country')
    serializer_class = CarSerializer


class CountrySerializer(serializers.ModelSerializer):
class Meta:
    model = country
    fields = ('country_name',)

class CarSerializer(serializers.ModelSerializer): 
    car_country = CountrySerializer()

    class Meta:
        model = car
        fields = ('car_number','car_country',)

我现在得到的结果如下:

[
    {
        "car_number": "45678",
        "car_country": {
            "country_name": "Europe/UK"
        }
    },
    {
        "car_number": "3333333",
        "car_country": {
            "country_name": "Europe / Netherlands"
        }
    },
    {
        "car_number": "11111111111",
        "car_country": {
            "country_name": "Europe/UK"
        }
    }
]

1 个答案:

答案 0 :(得分:0)

  

您的班级名称应以大写字母开头。

要返回具有相关car_numbers数量的国家/地区列表,请先将related_name添加到模型中,如下所示:

class Car(models.Model):
    car_number = models.CharField(verbose_name='VIN',max_length=11,unique=True,blank=False ,validators=[numeric])
    car_country = models.ForeignKey('Country', verbose_name='Country',blank=True, null=True, default=1, on_delete=models.PROTECT, related_name='cars')

然后您可以在视图中的查询中使用annotate()order_by(),如下所示:

from django.db.models import Count

class CarViewSet(viewsets.ModelViewSet):
    queryset =  Country.objects.all().annotate(car_amount=Count('cars')).order_by('-car_amount')
    serializer_class = CountrySerializer

要获得正确的输出,我们使用SerializerMethodField()来捕获特定Car的{​​{1}}对象的数量,如下所示:

Country

输出应如下所示:

class CountrySerializer(serializers.ModelSerializer):
    count_cars = serializers.SerializerMethodField(read_only=True)

    def get_count_cars(model):
        return model.cars.all().count()

    class Meta:
        model = Country
        fields = ('country_name' 'count_cars',)

如果您希望输出是递增而不是递减,请从[ { "country_name": "Europe/UK", "count_cars": 10 }, { "country_name": "Netherlands", "count_cars": 6 }, { "country_name": "Belgium", "count_cars": 3 }, ] 中删除-

降序,基于汽车数量:

order_by()

升序,基于汽车数量:

Country.objects.all().annotate(car_amount=Count('cars')).order_by('-car_amount')